아끼는 팔찌가 끊어졌다.

소원이 이루어지려나, 생각하다가 문득 소원을 빈 적이 없다는 것을 깨달았다

언니가 옆에서 지금이라도 빌어, 했다

그렇지 지금이라도 빌면 되는거지 ! 

비즈 하나하나 좋아하는 걸 골라 매듭을 묶어 손수 만든 팔찌라서 더 정이 갔는데

보는 사람마다 참 잘 어울린다고 하면 내가 만들었다고 자랑하곤 했다

이제 내 팔에 없는 것이 아쉽지 않을 만큼 굉장한 소원을 빌겠다고 다짐했다

밥을 먹으면서 계속 생각했다. 무엇을 빌어야 할까?

이 틈을 타 요즈음의 내 속마음을 들여다 볼 수도 있었다

학업.. 건강.. 회계사 합격.. 엄마아빠.. 수많은 단어들이 머릿속을 오고갔다

그런데 소원이라는 것은, 나의 노력으로만으로는 완성되지 않는 운의 요소가 들어간 것이어야 한다고 생각한다

기적이라던가 

학업적인 부분은 내가 노력하면 되는데.. 생각하다 머릿속을 스친 한 친구가 있었다

그 친구의 부모님이 어제보다 오늘 더, 오늘보다 내일 더 건강했으면 좋겠다고 빌었다

그리고 더 많은 좋은 추억을 함께 쌓았으면

믿어봐 저건 내가 정말 아끼는 소원팔찌야

'DIARY' 카테고리의 다른 글

10.05.25  (0) 2025.10.06
10.15.24  (4) 2024.10.16
09.26.24  (2) 2024.09.27
09.18.24  (6) 2024.09.19
09.04.24  (2) 2024.09.05

아아 추석이다

명절이라는 것은 사람 마음을 참 요상하게 만든다.

어린 시절에는 할머니집, 고모, 각종 친척집들을 하루종일 동분서주하느라 정신이 없었는데 이번 추석은 서울에서 언니랑 둘이 보낸다. 서울이 이렇게 고요한 적이 있었던가.. 알바 끝나고 오후에는 거실에서 비가 주룩주룩 오는 창밖을 바라보고 있는데 도로에 차가 한 대도 없었다. 비가 와서 괜시리 더 울적했다. 북적북적, 사람냄새가 그리운 순간이었다.

제기동역 에스컬레이터 공사장 내부에 한 인부가 보였다. 연휴에도 일을 하시는구나.. 남들 쉴 때도 일을 해야하거나 더 바쁜 직업들에 대해 생각했다. 오, 주식 시장은 쉬지 않을테니 펀드매니저들은 바쁘겠군. 추석에 고향에 가는 사람들을 실어 나르는 철도 기관사와 비행기 조종사들을 생각했다. 나, 연휴에 혼자서 쉴 수 있다는 것만으로 감사한 일이었구나. 

그래도 명절이라고 아침엔 언니랑 목욕을 갔다왔다. 뽀송해진 몸과 마음에 잠깐이나마 기대었다. 알바 가는 길에는 주룩주룩 내리는 비를 머금은 은행잎도 보았다. 노란 은행잎 위에 자리잡은 비구슬이 예뻐 사진을 찍어왔다. 그런데 젠장 갑자기 머리가 너무 아파왔다. 결국 터덜터덜 집으로 걸어와 약을 먹고 세 시간을 내리 잤다. 요즈음 잠이 많이 부족했나보다. 이렇게 내 몸상태를 알 수 있으니 다행이었다.

 

몇 해째 명절을 이렇게 보내며 다짐한 것이 있다. 나는 정말로, 따뜻하고 북적북적한 명절을 내 아이들에게 선사해 줘야지!

서로 한 해동안 어떻게 지냈는지 다정히 묻고 용돈을 쥐어주며 토닥이고, 편 갈라 윷놀이 한 판하고 기름냄새 잔뜩 배이게 전도 부쳐먹어야지

가족의 안정감과 든든함을 느끼게 해줄거다. 받지 못한 것도 줄 수는 있기에 

 

요즈음은 맛있는 음식을 먹는 시간, 혼자 가만히 앉아서 생각하거나 글을 쓰는 시간, 달리기 하는 매 순간, 그리고 독서하는 시간이 좋다. 특히 지하철이나 버스 등 이동시간을 독서시간으로 활용하는데, 가방에 든 책 하나의 무게가 참 든든하다.

어제 언니랑 얘기를 하다가 sns와 쇼츠 등의 폐해에 대한 이야기가 나왔다. 우리들이 실험쥐가 된 것마냥, 언니가 무료한 요즈음 그것들을 자주 경험했더니 마음이 더 불안해지고 조급해진 것 같다고 했다. 전적으로 동의했다 !! 나는 한 10개월정도 전부터 sns를 자주 하지 않는다. 공부도 공부지만, sns는 가공되고 남들에게 보여주고 싶은 모습을 추린 콘텐츠가 많은 비중을 차지하는 것 같다. 수많은 비난과 평가, 원치않는 과도한 정보가 쏟아져 들어오고 눈과 뇌는 깨어있는 모든 시간 피로하다. 사실 나는 x세대에 살고싶다. 연락 한 통을 하려면 삐삐 치러 가야하는 그 시절 ㅎㅎ 편지와 메모가 더 자주 왕래하던 그 시절이 궁금하다. 어쨋든, 사실 그런 이유 뿐만이 아니라 왜인지 요즘은 마음이 조급하다. 나와 다른 사소한 것 하나도 이해하기가 힘들고 화가 정말 없는 내가 화도 짜증도 자꾸 나고 심지어 ? 그것을 표출한다

음... 마음의 명상이 필요한 시간인가보다. 당분간은 규칙적인 생활을 하며 해야 할 것에 집중하는 시간이 필요한 것 같다. 오히려 좀 피곤해도 매일 일찍 일어나고 규칙적으로 살다보면 마음이 점차 안정됨을 느낀다. 어떻게 해야 할지는 알고있는 듯 하니 다행이다. 

 

오후 알바 때 스카에 고3들이 많이 보였는데, 수능을 한 달 남짓 앞둔 시점이라 연휴에도 열심이다 싶더라. 그래서 소심하지만 응원의 말을 남기고 왔다 ㅎㅎㅎ 대견한 아이들.. 뭐든 본인의 삶에 최선을 다하는 것은 참 멋지다 

 

비구슬. 얼마 전 국현미에서 본 김창열 작가의 회고전이 생각났다

 

 

 

고3 멘토리들을 위한 소심한 응원

 

 

 

요즈음 읽고있는 책들

 

'DIARY' 카테고리의 다른 글

10.12.25  (0) 2025.10.12
10.15.24  (4) 2024.10.16
09.26.24  (2) 2024.09.27
09.18.24  (6) 2024.09.19
09.04.24  (2) 2024.09.05

무산소보다 유산소에 빠진 요즘이다!

그래서 나의 유산소 루틴을 적어보고자 한다 ㅎㅎ

 

나는 한 가지 운동을 오랫동안 하는 걸 정말 지겨워하는지라

유산소도 다양한 종류를 번갈아가며 하는 걸 좋아한다!

다 자기에게 맞는 방식이 있으니 찾아보시길 ㅎㅎ

 


1. Treadmill (런닝머신)

 

요즘 가장 많이 하는 기구이다.

러닝을 가기 어려울 때 뛰기도 하는데, 가장 좋아하는 건 재밌는 드라마 4~50분 틀어놓고 인클라인으로 걷기!

빨리 걸을 필요도 없다.. 왜냐면 유산소는 최소 20분 이상 지나야 지방이 타기 때문에 30~1시간 천천히 걸으면 많이 힘들지 않다.

인클라인은 10~12사이로 놓고 타는 편이고, 속도는 2.5~3.0 왔다갔다 한다. 

상당한 오르막을 30분 이상 걷는 거기 때문에 40~50분 기준 거의 4~500칼로리 정도 소모된다!! 짱이지

 

가끔 20분 인클라인으로 걷고 15~20분은 평지에서 속도 5.5 정도로 설렁설렁 뛰기도 한다!

아무래도 러닝 대신이니까.. 연습겸 체력도 유지할겸해서!!

아무튼 최애 기구..런닝머신 알라뷰

 

 

 

2. 천국의계단

 

솔직히 싫어한다.. 왜냐구? 그냥 너무 힘들자나..

특히 하체한 날은 절대 안 한다!! 죽음을 맛볼거야

등 한 날에 가끔 하는데 20분 이상 해본 적은 없는 듯..? 

속도 7 정도로 10분 타다가 마지막 10분은 7, 9 왔다갔다 인터벌로 해주면 구웃

 

그치만 싫어.. 

그리고 천국의계단은 깡마른 사람이 아니면 다리가 두꺼워진다는 소문도 있다..

 

 

 

 

3. 마이마운틴

 

땀 줄줄 흐르는 마이마운틴!

런닝머신 인클라인이랑 다를 바가 없다

이것도 비슷하게 타는 듯! 근ㄷㅔ 40분까지만 딱 타봤음..

 

 

 

 

4. 사이클

 

우리 헬스장엔. ㅠ

사이클이 없다... 이럴수가

정말 좋아하는데 없어서 아쉽다.

이것도 드라마 틀어놓고 30분 타면 뚝딱


적어놓고 보니 별 거 없지만 모~ 기록용이니까 ~~

그렇담 안뇽

베트남 가기전에 다이어트 열심히 할거다! ✌🏻

 

'WORKOUT' 카테고리의 다른 글

골프 레슨 끝 ⛳️  (4) 2024.10.13
[골프] 레슨 4일차  (0) 2024.09.19

Week 5

: Data Structures


 

Lecture Contents

 

 

  • Data structures are forms of organization in memory.

 

 

1. Stacks and Queues

 

  • Queues : one form of abstract data structure (enqueued, dequeued)
  • Stacks (push, pop)
FIFO First in first out
LIFO Last in first out
typedef struct
{
    person people[CAPACITY];
    int size;
}
stack;

- Limitation of the code above : unable to grow as items are added to it.

 

 

 

 

2. Resizing Arrays

 

There's an array :

 

In memory, there are other values being stored by other programs, functions, and variables.

 

If you want to store a fourth value '4' in our array. 

You can allocate a new area of memory of size 4 and move the old array to a new one.

This new area of memory would be populated with garbage values

 

 

However, it's bad designed - Every time we add a number, we have to copy the array item by item.

It would be nice if we were able to put the '4' somewhere else in memory. (this would no longer be an array though because it's not contiguous)

 

list.c

#include <stdio.h>

int main(void)
{
	//List of size 3
    int list[3];
    
    //Initialize list with numbers
    list[0] = 1;
    list[1] = 2;
    list[2] = 3;
    
    //Print list
    for (int i = 0; i < 3; i++)
    {
    	printf("%i\n", list[i]);
    }
}

 

We can leverage our understanding of pointers to create a better design in this code:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	//List of size 3
    int *list = malloc(3 * sizeof(int));
    if (list == NULL)
    {
    	return 1;
    }
    
    //Initialize list of size 3 with numbers
    list[0] = 1;
    list[1] = 2;
    list[2] = 3;
    
    //List of size 4
    int *tmp = malloc(4 * sizeof(int));
    if (tmp == NULL)
    {
    	free(list);
    	return 1;
    }
    
    //Copy list of size 3 into list of size 4
    for (int i = 0; i < 3; i++)
    {
    	tmp[i] = list[i];
    }
    
    //Add number to list of size 4
    tmp[3] = 4;
    
    //Free list of size 3
    free(list);
    
    //Remember list of size 4
    list = tmp;
    
    //Print list
    for (int i = 0; i < 4; i++)
    {
    	printf("%i\n", list[i]);
    }
    
    //Free list
    free(list);
    return 0;
}
  • Notice that the 'tmp' list was created.
  • free(list) : since the block of memory that list points to is no longer used.

 

 

 

3. Linked Lists

 

  • three useful primitives
struct a data type that you can define yourself
. dot notation allows you to access variables inside that structure
* is used to declare a pointer or dereference a variable

 

  • -> operator : goes to an address and looks inside of a structure

A linked list is one of the most powerful data structures within C. It allows you to include values that are located at varying areas of memoryThey allow you to dynamically grow and shrink the list as you desire.

 

Three values stored at three different areas of memory :

We could utilize more memory to keep track of where the next item is :

We would keep one more element in memory, a pointer, that keeps track of the first item in the list.

 

These boxes are called nodes.

A node contains both an item (int number) & a pointer called next.

typedef struct node
{
    int number;
    struct node *next;
}
node;

 

 

Let's implement this picture above in code:

 

#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct node
{
	int number;
    struct node *next;
}
node;

int main(int argc, string agrv[])
{
	//Memory for numbers
    node *list = NULL;
    
    //For each command-line argument
    for (int i = 1; i < agrc; i++)
    {
    	//Convert argument to int
        int number = atoi(argv[i]);
        
        //Allocate node for number
        node *n = malloc(sizeof(node));
        if (n == NULL)
        {
        	return 1;
        }
        n->number = number;
        n->next = NULL;
        
        //Prepend node to list
        n->next = list;
        list = n;
    }

	//Print numbers
    node *ptr = list;
    while (ptr != NULL)
    {
    	printf("%i\n", ptr->number);
        ptr = ptr->next;
    }
    
    //Free memory
    ptr = list;
    while (ptr != NULL)
    {
    	node *next = ptr->next;
        free(ptr);
        ptr = next;
    }
}

 

  • Inserting into the list : O(1)
  • The amount of time required to search this list : O(n)

 

Pros

-Since linked lists are not stored in a contiguous block of memory, they can grow as large as you wish.

 

Cons

-More memory is required to keep track of the list instead of an array. (Pointer)

-Binary search is not possible in a list constructed as above.

 

 

★ 헷갈렸던 NULL 개념 정리 

type something == NULL;

something이 아무것도 pointing 하고있지 않음을 의미함.

 

 

You can sort your list as items are added :

#include <cs50.h>
#include <stdio.h>
#include <stdlib.h>

typedef struct node
{
	int number;
    struct node *next;
}
node;

int main(int argc, char *argv[])
{
	node *list = NULL;
    
    for(int i = 1; i < agrc; i++)
    {
    	int number = atoi(agrv[i]);
        node *n = malloc(sizeof(node));
        
        if(n == NULL)
        {
        	return 1;
        }
        n->number = number;
        n->next = NULL;
        
        if(list == NULL)
        {
        	list = n;
        }
        
        else if(n->number < list->number)
        {
        	n->next = list;
            list = n;
        }
        
        else
        {
        	for (node *ptr = list; ptr != NULL; ptr = ptr->next)
            {
            	if(ptr->next == NULL)
                {
                	ptr->next = n;
                    break;
                }
                
                if (n->number < ptr->next->number)
                {
                	n->next = ptr->next;
                    ptr->next = n;
                    break;
                }
            }
     }
     
     for (node *ptr = list; ptr != NULL; ptr = ptr->next)
     {
     	printf("%i\n", ptr->number);
     }
     
     node *ptr = list;
     while (ptr != NULL)
     {
     	node *next = ptr->next;
        free(ptr);
        ptr = next;
    }
}

 

 

 

 

 

4. Trees

 

 

  • Binary search trees : another data structure to store data more efficiently

  • The center value becomes the top of a tree.
  • Those that are less than the center value are placed to the left.
  • Those values that are more than the center value are to the right.

-Pointers can be used to point to the correct location of each area of memory.

 

In code :

 

-Search time : O(logn)

 

 

 

 

 

5. Dictionaries

 

  • Dictionaries : another data structure
  • They have a key and a value. (like actual book-form dictionaries that have a word and a definition)
  • The holy grail of algorithmic time complexity = O(1) or constant time
  • Dictionaries can offer this speed of access through hashing.

 

 

 

 

 

6. Hashing and hash Tables

 

  • Hashing : the idea of taking a value and being able to output a value that becomes a shortcut to it later.
  • A hash function : an algorithm that reduces a larger value to something small and predictable.
  • A hash table : a combination of both array and linked lists. An array of pointers to nodes.

 

A hash table could be imagined as follows:

- An array of alphabet

-When collisions happen, it can be reduced by improving your hash table and hash algorithm.

 

However, it takes up massive amount of memory.

 

A hash algorithm:

 

In code:

#include <ctype.h>

unsigned int hash(const char *word)
{
	return toupper(word[0]) - 'A';
}

 

 

 

 

 

7. Tries

 

  • Tries : another form of data structure
  • always searchable in constant time !
  • Downside : take up a large amount of memory

For example, a word 'Toad' would be stored as follows:

 

Toadette and Tom would be stored as:

 

 


5주차에서는 Queues, Linked lists, Trees, Dictionaries, 그리고 Tries 까지 다양한 data structure의 개념과 활용 방법에 대해서 알아보았다. 컴퓨터의 메모리를 정리할 때 어떤 data structure을 사용하느냐에 따라 속도와 메모리가 차지하는 크기가 달라지기 때문에 중요한 영향을 끼친다. 저번주에 이어서 보이지 않는 메모리 영역을 다루고, pointer의 개념이 아직 미숙해서 처음으로 강의를 다시 뒤로 돌려 반복해서 듣기도 한 내용들이다. 아직까지 완벽하게 이해했다고 자신할 수는 없지만, Section과 Pset5를 듣고 고민하는 과정에서 더 큰 이해를 할 수 있길!! 오늘도 수고 많았다 안뇨옹

'CS50' 카테고리의 다른 글

[CS50] Pset 4 : Volume, Filter-less, Recover  (5) 2024.10.22
[CS50] Week 4 Section  (1) 2024.10.10
[CS50] Week 4 Review  (4) 2024.10.09
[CS50] Pset 3 : Sort, Plurality, Runoff  (1) 2024.10.06
[CS50] Week 3 Section  (2) 2024.10.03

 

Pset 4이 왜 이렇게 늦었냐면... 코딩에 약간 벽을 느끼고 1보 후퇴했기 때문..

ㅎㅎ 사실 논 건 아니고 매일 시간 내서 문제를 풀려고 노력은 했지만 너무 어려워서 한참 걸렸어요..ㅠㅠ

뒤로 갈수록 배운 거에서 나오는 게 아니고 응용을 요구합니다 !!!

약간.. 개념 배우고 심화 문제 나오는 수능같은 그런 느낌

진짜로 literally 손으로 머리 싸매고 낑낑댐..

 

어쨋든 어제 두세시간을 쏟고 마지막 과제를 제출하고 나서야 문풀 리뷰를 할 수 있게 되었네용

리뷰하면서 못 다한 이해를 해보도록 하겠습니다 ^~^

1보 후퇴엔 3보 전진~~

 

레츠고 !


4-1) Volume

 

: 볼륨 조절하기

WAV files store audio as a sequence of “samples”: numbers that represent the value of some audio signal at a particular point in time. WAV files begin with a 44-byte “header”, and after the header, it contains a sequence of samples, each a single 2-byte (16-bit) integer representing the audio signal at a particular point in time. Scaling each sample value by a given factor has the effect of changing the volume of the audio. Write a program to modify the volume of an audio file.

 

 

<Distribution code>

  • The program should accept three command-line arguments. (input, output, factor)
  • The program should read the header from the input file and write the header to the output file.
  • The program should then read the rest of the data from the WAV file, one 16-bit(2-byte) sample at a time. It should multiply each sample by the factor and write the new sample to the output file. 

 

 

 

atof() : used to convert a string into a floating-point number

 


//TODO #1

: Copy header from input file to output file

uint8_t header[HEADER_SIZE];
fread(header, HEADER_SIZE, 1, input);
fwrite(header, HEADER_SIZE, 1, output);

* HEADER_SIZE는 이미 44로 defined 됨.

 

★Parameters of fread ()

fread(a pointer to a block of memory, size of each element, number of elements, a pointer to the FILE object);

 

 

 

 

//TODO #2

: Read samples from input file and write updated data to output file

int16_t buffer;
while (fread(&buffer, sizeof(int16_t), 1, input)
{
    buffer *= factor;
    fwrite(&buffer, sizeof(int16_t), 1, output);
}

 

 


4-2) Filter-less

 

: 사진에 필터 입히기

A file format (like BMP, JPEG, or PNG) that supports “24-bit color” uses 24 bits per pixel. A 24-bit BMP uses 8 bits to signify the amount of red in a pixel’s color, 8 bits to signify the amount of green in a pixel’s color, and 8 bits to signify the amount of blue in a pixel’s color. If the R, G, and B values of some pixel in a BMP are, say, 0xff, 0x00, and 0x00 in hexadecimal. In this problem, you’ll manipulate these R, G, and B values of individual pixels, ultimately creating your very own image filters.

 

 

<Distribution code>

 

 


//TODO #1

: Implement grayscale (흑백 필터)

 

We should make sure the red, green, and blue values are all the same value. But what value to make them?

→ If the original red, green, and blue values were all pretty high, then the new value should also be pretty high. If the original values were all low, then the new values should also be low.

 

You can take the average of the red, green, and blue values of each pixel to determine what shade of grey to make the new pixel. 

 

//Loop over all pixels
for(int i = 0; i < height; i++)
{
	for(int j = 0; j < width; j++)
    {
	//Take average of red, green, and blue
    int average = round((image[i][j].rgbtRed + image[i][j].rgbtGreen + image[i][j].rgbtBlue) / 3.0);
    
    //Update pixel values
    image[i][j].rgbtRed = average;
    image[i][j].rgbtGreen = average;
    image[i][j].rgbtBlue = average;
    }
}

 

 

The result being like :

 

 

 

 

//TODO #2
: Implement Sepia (오래된 붉은갈색 느낌 필터)

 

For each pixel, the sepia color values should be calculated based on the original color values per the below:

sepiaRed = .393 * originalRed + .769 * originalGreen + .189 * originalBlue
sepiaGreen = .349 * originalRed + .686 * originalGreen + .168 * originalBlue
sepiaBlue = .272 * originalRed + .534 * originalGreen + .131 * originalBlue

The results may not be an integer, but each value could be rounded to the nearest integer.

//Loop over all pixels
for (int i = 0; i < height; i++)
{
	for (int j = 0; j < width; j++)
    {
    	//Compute sepia values
        int sepiaRed = round(.393 * image[i][j].rgbtRed + .769 * image[i][j].rgbtGreen + .189 * image[i][j].rgbtBlue);
        int sepiaGreen = round(.349 * image[i][j].rgbtRed + .686 * image[i][j].rgbtGreen + .168 * image[i][j].rgbtBlue);
        int sepiaBlue = round(.272 * image[i][j].rgbtRed + .534 * image[i][j].rgbtGreen + .131 * image[i][j].rgbtBlue);
        
        if(sepiaRed > 255)
        {
        	sepiaRed = 255;
        }
         
        if(sepiaGreen > 255)
        {
        	sepiaGreen = 255;
        }
        
        if(sepiaBlue > 255)
        {
        	sepiaBlue = 255;
        }
        
        //Update pixel with sepia values
        image[i][j].rgbtRed = sepiaRed;
        image[i][j].rgbtGreen = sepiaGreen;
        image[i][j].rgbtBlue = sepiaBlue;
    }
}

 

 

The result being like:

 

 

 

 

//TODO #3

: Implement Reflect (수평으로 뒤집힌 필터)

 

  • Any pixels on the left side of the image should end up on the right, and vice versa.
//Loop over all pixels
for (int i = 0; i < height; i++)
{
	for (int j = 0; j < (width/2); j++)
    {
    	//Swap pixels
        RGBTRIPLE temp = image[i][j];
        image[i][j] = image[i][width-j-1];
        image[i][width-j-1] = temp;
    }
}

★ Notice that j loop is until (width/2) because only half of the pixels of a row should be reflected!

image[i][width-j-1] means the pixel on opposite side of a row.

 

 

The result being like:

 

 

 

 

//TODO #4

: Implement Blur (블러 처리된 필터) ★

 

가장 어려워서 며칠간 고민했던 부분!!

We will use "box blur", which works by taking each pixel and, for each color value, giving it a new value by averaging the color values of neighboring pixels. 

The new value of each pixel would be the average of the values of all of the pixels that are within 1 row and column of the original pixel (forming a 3x3 box). 

Ex) For pixel 6 : new value of averaged the original color values of pixels 1,2,3,5,6,7,9,10, and 11.

      For a pixel along the edge or corner, like pixel 15 : pixels 10,11,12,14,15and 16.

 

We are going to create a copy of image:

//Create a copy of image
RGBTRIPLE copy[height][width];
for(int i = 0; i < height; i++)
{
	for(int j = 0; j < width; j++)
    {
    	copy[i][j] = image[i][j];
    }
}

 

Let's write psedocodes first, stey-by-step!

//전체 이미지의 각 픽셀 iterate

	//copy 만들기
    
    //3x3 box 픽셀 iterate
    
    	//픽셀이 valid한 경우 (edge case, corner case 포함)
        
        	//각 픽셀에 새로운 RGB 값 할당
            
        //각 RGB 값의 평균을 copy에 직접 할당
        
        //전체 픽셀에 대해 copy 값을 image 값에 원래대로 할당

즉, 전체 이미지에서 3x3 사이즈의 픽셀 박스를 iterate하면서 각 RGB값의 평균을 새로이 할당하고, 마지막에는 copy에 할당한 값을 원래대로 image에 돌려놓으면 됩니다!

 


① 3x3 box 픽셀 반복문

★새로운 변수 int di, int dj를 만들어서 상하좌우 한 칸씩을 뜻하는 -1부터 1까지 반복하는 box iteration을 만든다.

이것을 전체를 반복하는 변수 i와 j에 더하여 전체 픽셀을 한정적인 3x3 box로 반복할 수 있게 새로운 변수 ni, nj로 정의한다.

 

 

② valid pixel 조건문

: 유효한 픽셀이라는 것은 edge나 corner 픽셀의 경우도 포괄해야 함을 뜻한다. 

  이는 새로이 정의된 변수 ni, nj가 0보다 크거나 같고 각각 height, width보다 작아야함을 의미한다. 

 

 

③ 새로운 RGB 값 할당하기

: 먼저, 새로운 RGB값을 담아둘 변수 Red, Green, Blue를 정의한 후 각각에 값을 할당한다.

: float으로 정의한 이유는 각 값이 딱 정수로 떨어지지 않을 수 있기 때문. 이렇게 정의하면 정확도가 올라갈 수 있다.

 

: 각 픽셀의 빨간색, 초록색, 파란색 값을 각각 Red, Green, Blue에 더해준다.

 

 

④ counter 만들기

: 평균을 구하기 위해서는 몇 개의 유효한 픽셀의 RGB 값이 더해졌는지 알아야 한다.

  따라서, 유효한 픽셀을 카운트 할 때마다 counter 변수를 하나씩 업 시켜준다.

 

먼저, counter 변수를 0으로 정의한다.

: 중요한 것은 counter을 0으로 정의하는 위치이다. 각 box를 반복한 후에 다시 0으로 reset 해야하기 때문에 box iteration 앞에 정의한다.

 

: 유효한 픽셀 조건문 안에 counter ++를 해준다. 

 

 

RGB 값 평균 구하고 할당하기

: RGB 값의 평균은 직접적으로 copy에 할당한다. 이 때 주의할 점은 변수 Red, Green, Blue 값이 float 이기 때문에 round()를 통해 가까운 정수로 변환해준다.

: 이 때에도 중요한 것은 위치이다. Box iteration 바깥에서 copy에 할당해준다. 

 

 

copy 값을 image 값으로 옮기기

각 픽셀의 값을 다 옮겨 할당해야 하므로, 전체 픽셀을 반복하는 for문 아래에서 할당시켜준다.

 

 

완성된 Blur 코드를 전체적으로 보면 다음과 같다:

 

 

The result being like:

 

 


4-3) Recover

 

: 삭제된 사진 복원하기

We spent the past several days taking photos around campus, all of which were saved on a digital camera as JPEGs on a memory card. Unfortunately, we somehow deleted them all! We’re hoping (er, expecting!) you can write a program that recovers the photos for us!

(약간 초등학교 수학 문제중에 달력을 찢었다.. 이런 거 생각났다 ㅋㅋㅋㅋㅋㅋ 왜 찢어.. 왜 삭제해..)

 

 

Background

  • JPEGs have "signatures", patterns of bytes that can distinguish them from other file formats. The first three bytes of JPEGs are 0xff, 0xd8 and 0xff.
  • The fourth byte is either 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, or 0xef. The fourth byte's first four bits are 1110.
  • Digital cameras only write to cards in units of 512 B. (block size = 512 bytes
    →It means you can read 512 of memory card's bytes at a time for efficiency's sake.

위 그림처럼 각 색이 각 JPEG 파일을 의미한다. JPEG가 시작하는 블럭이 있고, 시작하지 않는 블럭이 있다.

 

 

 

Let's write psedocodes first!

//Accept a single command-line argument

//Open the memory card

//While there's still data left to read from the memory

	//Create JPEGs from the data

 

 

① single command-line argument

: 하나의 command-line argument가 아닐 시 에러 메세지로 경고한다. (argc != 2)

 

 

② open the memory card

: card memory로 가서 argv[1]을 여는데, read 모드로 연다. ("r") 만일 file이 제대로 열리지 않을 시 에러메세지로 경고한다.

 

 

③ memory에서 더 이상 읽을 데이터가 없을 때까지 조건문

: 파일에서 데이터를 읽을 때, 일시적으로 그 데이터를 보관할 "buffer"가 필요하다. 데이터가 512 bytes로 저장되어 있으므로, 해당 사이즈로 buffer을 만들면,

uint8_t buffer[512];

이렇게 만들 수 있겠지만, 코드에 constant(magic number)를 쓰는 것은 바람직하지 않으므로 보완하여 다시 쓸 수 있다. 

Notice that there's no ; when you use #define

 

그 다음, fread()를 사용하여 계속해서 남은 데이터를 읽는다. 이 때, fread() returns the number of bytes it has read, so make sure that the condition is equal to BLOCKSIZE(512).

 

 

④ If start of new JPEG

: 앞에서 memory block은 JPEG의 시작일 수도, 아닐 수도 있다고 언급했다. 먼저 JPEG의 시작일 경우 조건문을 생각해보자.

  buffer[BLOCKSIZE] 중 첫 번째~세 번째의 bytes는 알고 있다.

if (buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && buffer[3] == ?)

 

여러가지 경우의 수가 있는 네 번째 byte는 어떻게 표현할까?

 

★ bitwise arithmetic (operation) = 비트 연산

: bit 단위로 연산을 할 때 사용되는 연산자. 

 

&는 대응되는 비트가 모두 1이면 1을 반환한다.  예를 들어보자.

byte binary
0xf0 1111    0000
buffer[3] whatever
0x  0 1111     0000

0xf0을 binary로 변환시키면 1111  0000이 되는데, 이는 buffer[3]가 뭐가 됐든 대응했을 때 결과가 1111  0000이 나온다는 것을 의미한다. 이는 결국 0x0으로 나올 것인데, 앞에서 0xe. 라고 했으므로 0xe0이 될 것이다.

 

따라서 다음과 같은 조건문을 쓸 수 있다:

 

 

JPEG이 시작됐을 경우, 순서에 맞게 파일을 새로운 이름으로 저장해야 한다. 순서를 알기 위해 먼저 counter을 정의해서 파일 수를 센다.

★ 000부터 시작해야 하므로 counter = -1로 정의한다.

또한, 파일을 넣어둘 변수 filename과 새로 쓴 JPEG 파일을 저장할 새로운 파일 outputFile을 정의한다.

%03i.jpg : %03을 앞에 붙이는 것은 세 자리 int 자리를 의미한다. 

 

그리고 outputFile에 새로이 쓴다:

 

 

 

이미 JPEG파일을 찾은 경우 

: outputFile을 닫는다. 하지만 이 부분은 새로운 파일을 열기 전에 먼저 실행되어야 하므로 앞의 fwrite 앞에 위치한다. 

 

 

 

새 JPEG 파일의 시작점이 아닌 경우 (중간 혹은 끝)

: 계속 write 한다.

 

 

 

⑤ 열어둔 파일을 모두 닫기

 

 

완성된 Recover 코드를 보면 다음과 같다 :

 

 


원래 시작보다 중간이 더 어려운 거라고 했나요..

누가 그랬더라.. 하지만 뭐든지 "지옥의 중간 과정"을 잘 넘어가면 더 깊은 깨달음이 있을 거라는 얘기를 어디선가 들은 것 같아!!

그러니까 포기하지 않는 것이 중요한 것이겠쬬 움움

 

다음 Week 5도 강의 듣고 내용 정리해서 오겠습니다아 ~.~ 화 이 팅 얏호!

'CS50' 카테고리의 다른 글

[CS50] Week 5 Review  (4) 2024.10.28
[CS50] Week 4 Section  (1) 2024.10.10
[CS50] Week 4 Review  (4) 2024.10.09
[CS50] Pset 3 : Sort, Plurality, Runoff  (1) 2024.10.06
[CS50] Week 3 Section  (2) 2024.10.03

 

이 세상에 나라는 존재가 있다는 게 문득 감사하고 신기하다. 

나뭇잎도 물고기도 바퀴벌레도 아니고 인간으로

이스라엘도 러시아도 남극도 아니고 대한민국에 여자아이로 태어나서 

대멸종시기도 일제강점기도 조선시대도 아니고 21세기에 첨단 기술을 누리면서

하루살이처럼 며칠도 매미처럼 2주도 물고기처럼 5년도 강아지처럼 15년도 아니고 무려 100살까지 살 수 있다는 게!!

 

새삼스레 감사해진다...!!

 

이 큰 우주에서 우리 은하계, 태양계에서 또 거대한 지구에서 조그마한 대한민국에서 

그 중에 또 이 도시에서, 동네에서, 학교에서 만난 모든 인연들이 비록 잠시 스쳤을지라도

엄청나게 대단하게 느껴진다. 

이건 몇 분의 1 확률일까??? 아무튼간에 엄청난 숫자임은 틀림 없다..

 

그래서 으레 천문학자들이 그렇다고 하듯이 모든 것들에 초연해진다. 

반대로 모든 것들에 의미를 부여하게 되기도 한다. 

대체로 모든 것들에 의연하고 감사해진다. 

나를 괴롭히던 것들이나 붕 띄워주던 것들도 그냥 그러려니 하게 된다. 

모든 세상을 사랑해야지! 그 속의 모든 존재도 사랑해야지! 

 

세상이 모두 바뀌어도 변하지 않는 것은 사랑인 것 같다. 

혹자는 사랑도 변한다지만, 변하는 건 사랑이 아니라 사람이다

 

그러니까 나는 모든 것을 그냥 사랑만 하고싶다

 

'DIARY' 카테고리의 다른 글

10.12.25  (0) 2025.10.12
10.05.25  (0) 2025.10.06
09.26.24  (2) 2024.09.27
09.18.24  (6) 2024.09.19
09.04.24  (2) 2024.09.05


오늘로 8회에 걸친 골프 레슨이 끝나따 !

까먹기 전에 프로님의 마지막 가르침 남기기
ㅎ.ㅎ


<아이언>

  • 휘두르지 말고 땅을 치듯이 툭툭
  • 백스윙 ⭐️: 더 뒤로 몸통 돌리면서 쭉 올리기 / 헤드가 약간 뒤로 / 오른쪽 무릎 쭉 피지 말고 살짝 굽히기 -> 뒤땅 안 나올 가능성 높음
  • 무게중심 왼쪽
  • 머리와 어깨 떨어지지 않게 약간 업
  • 생각보다 발 넓게 서기
  • 헤드 위치: 공 바로 옆에, 스틱 각 살짝 왼쪽으로 기울게



<하이브리드>

  • 아이언과 동일 (백스윙도)
  • 공이 아이언보다 왼발에 가까이, 조금 더 멀리 서기



<드라이브>

  • 왼발 뒤꿈치에 공, 생각보다 좁게 서기
  • 왼쪽 골반이 버틴다는 느낌으로 회전
  • 공이 헤드에 먼저 맞고 몸 회전
  • 헤드 속도 늘려 거리 늘리기!
  • 헤드 위치: 공보다 살짝 아래



<공통>

  • 오른발 뒤로 땡기기(자꾸 앞으로 나감)
  • 머리와 몸통 다운되지 않게

'WORKOUT' 카테고리의 다른 글

[헬스] 유산소  (4) 2024.10.28
[골프] 레슨 4일차  (0) 2024.09.19

 

1. Pointers (and why to use them)

 

  • A variable : a name for some value that can change → has an address somewhere in memory
  • type : int *
  • name : p
  • value : &calls (the address of calls)

 

Reasons to use pointers

 

Pointers enable additional capabilities like:

  • You could write a function that allows you to pass something in by reference and not just by copy.
    The code you write is cleaner as a result.
  • You could ask your program for dynamic memory depending on what the user actually needs.
    Your programs can now scale their usage of memory according to user behavior.

 

 


 

2. Passing by Copy vs Passing by Reference

 

 

<Passing by Copy>

This seemed to be swapped in swap, but it's still the same in main function !

 

 

<Passing by Reference>

By copying the addresses of a and b(the pointer to a/ the pointer to b), we actually copy in the address, and we change the values exactly where those values currently in memory.

 

 

Let's debug this in VS Code and see step-by-step:

Here's my code swapping two values, a and b.

If I run debug50 :

① Notice that a = 10, b = 50

    Let's step into the swap function!

② In variable window, you can see the addresses of a and b now. (&a, &b)

    Let's step over :

 

③ Notice that the value of location a(*a = 10) is handed over to temp.(temp = 10)

    Let's step over:

 

④ Now, the value of b(*b = 50) is handed over to a.(*a = 50)

    Let's step over for the last time :

 

⑤ Notice that the value of temp(10) is handed over to *b.(*b = 10)

    And now you can check that a and b are swapped.

 

 

 


 

3. FILE I/O

 

 

We can also open up files, read data from them, and write data to those files!

fopen opens a file for future reading/ writing.
fclose closes a file.

 

Always fclose all files you fopen!

 

fopen

"r" means 'read' mode.

"w" means 'write' mode.

 

fclose

 

 

 

<Reading and Writing>

fread reads data from a file into a buffer*.
fwrite writes data from a buffer* to a file.

*a buffer is a chunk of memory that can temporarily store some data from the file.

 

Why do we need a buffer?

→ We often don't know how big a file is, so the best we can do is to look at small bits of it, not the entire file itself.

 

 

<Reading from a File>

  • From where are you reading?
  • To where are you reading?
  • What size is each block of data you want to read? (ex. text file-1 byte/ image file-3 bytes)
  • How many blocks do you want to read?

fread(Towhere, what size , how many , Fromwhere);

ex) fread(buffer, 1, 4, f);

 

 

<Practice with Reading>

  • Create a program, pdf.c, that opens a file given as a command-line argument.
  • Check if that file is a PDF. A PDF always begin with a four-byte sequence, corresponding to these integers:
    37, 80, 68, 70

① Open up a file

② Create a buffer

③ Use fread to read 4 individual bytes from that file

④ Print those out

 

  • uint8_t : Unsigned Int of 8 bytes (always positive, takes 8 bits or 1 byte long)
                   Meaning, you can store a positive Integer with max number being 2^8-1.

If we use int buffer instead of uint8_t, we might not get the values we expect,

because int buffer[4] is 16 bytes long(an integer is 4 bytes long), whereas we're only going to read four of them.

 

 

 

 

<Writing to a File>

 

:basically the same as fread

fwrite(buffer, 1, 4, f);

 

'CS50' 카테고리의 다른 글

[CS50] Week 5 Review  (4) 2024.10.28
[CS50] Pset 4 : Volume, Filter-less, Recover  (5) 2024.10.22
[CS50] Week 4 Review  (4) 2024.10.09
[CS50] Pset 3 : Sort, Plurality, Runoff  (1) 2024.10.06
[CS50] Week 3 Section  (2) 2024.10.03

+ Recent posts