text:
<repo_name>cnsuhao/xadillax-topcoder<file_sep>/code-kawigiEdit/GearsDiv2.cpp
/**
 * The template of Topcoder
 * Author: XadillaX (<EMAIL>)
 */
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <deque>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <ctime>
using namespace std;

#define ZERO(x) (memset(x, 0, sizeof(x)))
#define SIZE(x) ((int)(x.size()))
#define LENGTH(x) ((int)(x.length()))
#define LL long long

/** Segment tree */
#define LC(x) ((x >> 1) + 1)
#define RC(x) ((x >> 1) + 2)

/** Math */
const double pi = acos(-1.0f);
const double eps = 1e-8;

class GearsDiv2
{
public:
    int getmin(string Directions);
};

int GearsDiv2::getmin(string Directions)
{
    int dp[100][2][2];
    for(int i = 0; i < LENGTH(Directions); i++)
    {
    	if(i == 0)
    	{
    		dp[i][0][0] = 1;
    		dp[i][0][1] = 10000000;
    		dp[i][1][1] = 0;
    		dp[i][1][0] = 10000000;
    	}
    	else
    	if(i == 1)
    	{
    		if(Directions[i] == Directions[i - 1])
    		{
    			dp[i][0][1] = 1;
    			dp[i][1][0] = 1;

    			dp[i][0][0] = 10000000;
    			dp[i][1][1] = 10000000;
    		}
    		else
    		{
    			dp[i][0][0] = 2;
    			dp[i][0][1] = 1;
    			dp[i][1][0] = 1;
    			dp[i][1][1] = 0;
    		}
    	}
    	else
    	if(Directions[i] == Directions[i - 1])
    	{
    		dp[i][1][0] = dp[i - 1][0][0];
    		dp[i][1][1] = dp[i - 1][0][1];

    		dp[i][0][0] = dp[i - 1][1][0] + 1;
    		dp[i][0][1] = dp[i - 1][1][1] + 1;
    	}
    	else
    	{
    		dp[i][1][0] = min(dp[i - 1][0][0], dp[i - 1][1][0]);
    		dp[i][1][1] = min(dp[i - 1][0][1], dp[i - 1][1][1]);

    		dp[i][0][0] = min(dp[i - 1][1][0], dp[i - 1][0][0]) + 1;
    		dp[i][0][1] = min(dp[i - 1][1][1], dp[i - 1][1][1]) + 1;
    	}

    	cout << "dp[" << i << "][0][0] = " << dp[i][0][0] << "; ";
    	cout << "dp[" << i << "][1][1] = " << dp[i][1][1] << "; ";
    	cout << "dp[" << i << "][0][1] = " << dp[i][0][1] << "; ";
    	cout << "dp[" << i << "][1][0] = " << dp[i][1][0] << "; ";
    	cout << endl;
    }

    int ans;
    int mi = LENGTH(Directions) - 1;
    if(Directions[mi] == Directions[0])
    {
    	ans = min(dp[mi][0][0], min(dp[mi][1][0], dp[mi][0][1]));
    }
    else
    {
    	ans = min(min(dp[mi][0][0], dp[mi][1][1]), min(dp[mi][0][1], dp[mi][1][0]));
    	//ans = min(dp[mi][0][0], min(dp[mi[1][0], min(dp[mi][0][1], dp[mi][1][1])));
    }

    return ans;
}

// BEGIN KAWIGIEDIT TESTING
// Generated by KawigiEdit 2.1.8 (beta) modified by pivanof
#include <iostream>
#include <string>
#include <vector>
using namespace std;
bool KawigiEdit_RunTest(int testNum, string p0, bool hasAnswer, int p1) {
	cout << "Test " << testNum << ": [" << "\"" << p0 << "\"";
	cout << "]" << endl;
	GearsDiv2 *obj;
	int answer;
	obj = new GearsDiv2();
	clock_t startTime = clock();
	answer = obj->getmin(p0);
	clock_t endTime = clock();
	delete obj;
	bool res;
	res = true;
	cout << "Time: " << double(endTime - startTime) / CLOCKS_PER_SEC << " seconds" << endl;
	if (hasAnswer) {
		cout << "Desired answer:" << endl;
		cout << "\t" << p1 << endl;
	}
	cout << "Your answer:" << endl;
	cout << "\t" << answer << endl;
	if (hasAnswer) {
		res = answer == p1;
	}
	if (!res) {
		cout << "DOESN'T MATCH!!!!" << endl;
	} else if (double(endTime - startTime) / CLOCKS_PER_SEC >= 2) {
		cout << "FAIL the timeout" << endl;
		res = false;
	} else if (hasAnswer) {
		cout << "Match :-)" << endl;
	} else {
		cout << "OK, but is it right?" << endl;
	}
	cout << "" << endl;
	return res;
}
int main() {
	bool all_right;
	all_right = true;

	string p0;
	int p1;

	{
	// ----- test 0 -----
	p0 = "LRRR";
	p1 = 1;
	all_right = KawigiEdit_RunTest(0, p0, true, p1) && all_right;
	// ------------------
	}

	{
	// ----- test 1 -----
	p0 = "RRR";
	p1 = 2;
	all_right = KawigiEdit_RunTest(1, p0, true, p1) && all_right;
	// ------------------
	}

	{
	// ----- test 2 -----
	p0 = "LRLR";
	p1 = 0;
	all_right = KawigiEdit_RunTest(2, p0, true, p1) && all_right;
	// ------------------
	}

	{
	// ----- test 3 -----
	p0 = "LRLLRRLLLRRRLLLL";
	p1 = 6;
	all_right = KawigiEdit_RunTest(3, p0, true, p1) && all_right;
	// ------------------
	}

	{
	// ----- test 4 -----
	p0 = "RRRRRRRLRRRRRRRLRLRLLRLRLRLRRLRLRLLLRLRLLRLLRRLRRR";
	p1 = 14;
	all_right = KawigiEdit_RunTest(4, p0, true, p1) && all_right;
	// ------------------
	}

	if (all_right) {
		cout << "You're a stud (at least on the example cases)!" << endl;
	} else {
		cout << "Some of the test cases had errors." << endl;
	}
	return 0;
}
// END KAWIGIEDIT TESTING
//Powered by KawigiEdit 2.1.8 (beta) modified by pivanof!
<file_sep>/README.md
# XadillaX @ TopCoder

This is my own code @topcoder.

<file_sep>/code/SRM589-DIV2/1000.cpp
/**
 * The template of Topcoder
 * Author: XadillaX (<EMAIL>)
 */
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <deque>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <ctime>
using namespace std;

#define ZERO(x) (memset(x, 0, sizeof(x)))
#define SIZE(x) ((int)(x.size()))
#define LENGTH(x) ((int)(x.length()))
#define LL long long

/** Segment tree */
#define LC(x) ((x >> 1) + 1)
#define RC(x) ((x >> 1) + 2)

/** Math */
const double pi = acos(-1.0f);
const double eps = 1e-8;

class FlippingBitsDiv2
{
public:
    int getmin(vector <string> S, int M);

    string str;
    int group;
    int tn1[2600], tnsum1[2600];
    int tn2[2600], tnsum2[2600];

    int dp1[2600][2];
    int dp2[2600][2];

    int calcsum(int l, int r)
    {
    	if(l > r) return 0;
    	int tot = tnsum1[r] - tnsum1[l - 1];
    	return tot;
    }
};

int FlippingBitsDiv2::getmin(vector <string> S, int M)
{
    str = "";
    for(int i = 0; i < SIZE(S); i++) str += S[i];
    group = LENGTH(str) / M;
    ZERO(tn1);
    ZERO(tn2);

    // init.
    for(int i = 0; i < group; i++)
    {
    	int op = i * M;
    	int ed = op + M;
    	for(int j = op; j < ed; j++)
    	{
    		if(str[j] == '0') tn1[i]++, tn2[group - i - 1]++;
    	}

    	dp1[i][0] = 100000;
    	dp1[i][1] = 100000;
    	dp2[i][0] = 100000;
    	dp2[i][1] = 100000;
    }

    // tnsum
    for(int i = 0; i < group; i++)
    {
    	if(i == 0) tnsum1[0] = tn1[0], tnsum2[0] = tn2[0];
    	else
    	{
    		tnsum1[i] = tnsum1[i - 1] + tn1[i];
    		tnsum2[i] = tnsum2[i - 1] + tn2[i];
    	}
    }

    // dp.
    for(int i = 0; i <= group; i++)
    {
    	if(i == 0)
    	{
    		dp1[i][0] = dp1[i][1] = dp2[i][0] = dp2[i][1] = 0;
    	}
    	else
    	if(i == 1)
    	{
    		// head -> tail
    		dp1[i][0] = tn1[i - 1];
    		dp1[i][1] = 1 + (M - tn1[i - 1]);

    		// tail -> head
    		dp2[i][0] = tn2[i - 1];
    		dp2[i][1] = 1 + (M - tn2[i - 1]);
    	}
    	else
    	{
    		// head -> tail
    		dp1[i][0] = min(
    			dp1[i - 1][0] + tn1[i - 1],
    			dp1[i - 1][1] + tn1[i - 1]
    		);
    		dp1[i][1] = min(
    			dp1[i - 1][0] + 2 + (M - tn1[i - 1]),
    			dp1[i - 1][1] + (M - tn1[i - 1])
    		);

    		// tail -> head
    		dp2[i][0] = min(
    			dp2[i - 1][0] + tn2[i - 1],
    			dp2[i - 1][1] + tn2[i - 1]
    		);
    		dp2[i][1] = min(
    			dp2[i - 1][0] + 2 + (M - tn2[i - 1]),
    			dp2[i - 1][1] + (M - tn2[i - 1])
    		);
    	}
    }

    int minans = 100000000;
    for(int i = 0; i <= group; i++)
    {
    	for(int j = 0; j <= group - i; j++)
    	{
    		int zzl = i;
    		int zzr = group - j - 1;

    		minans = min(minans,
    			min(dp1[i][0], dp1[i][1]) +
    			min(dp2[j][0], dp2[j][1]) +
    			calcsum(zzl, zzr)
    			);
    	}
    }

    return minans;
}

<%:testing-code%>
//Powered by KawigiEdit 2.1.8 (beta) modified by pivanof!
<file_sep>/code-kawigiEdit/GooseTattarrattatDiv2.cpp
/**
 * The template of Topcoder
 * Author: XadillaX (<EMAIL>)
 */
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <deque>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <ctime>
using namespace std;

#define ZERO(x) (memset(x, 0, sizeof(x)))
#define SIZE(x) ((int)(x.size()))
#define LENGTH(x) ((int)(x.length()))
#define LL long long

/** Segment tree */
#define LC(x) ((x >> 1) + 1)
#define RC(x) ((x >> 1) + 2)

/** Math */
const double pi = acos(-1.0f);
const double eps = 1e-8;

class GooseTattarrattatDiv2
{
public:
    int getmin(string S);
};

int GooseTattarrattatDiv2::getmin(string S)
{
    int maxsame = 0;
    map<char, int> mp;
    for(int i = 0; i < LENGTH(S); i++)
    {
    	mp[S[i]]++;
    	maxsame = max(maxsame, mp[S[i]]);
    }

    return LENGTH(S) - maxsame;
}

// BEGIN KAWIGIEDIT TESTING
// Generated by KawigiEdit 2.1.8 (beta) modified by pivanof
#include <iostream>
#include <string>
#include <vector>
using namespace std;
bool KawigiEdit_RunTest(int testNum, string p0, bool hasAnswer, int p1) {
	cout << "Test " << testNum << ": [" << "\"" << p0 << "\"";
	cout << "]" << endl;
	GooseTattarrattatDiv2 *obj;
	int answer;
	obj = new GooseTattarrattatDiv2();
	clock_t startTime = clock();
	answer = obj->getmin(p0);
	clock_t endTime = clock();
	delete obj;
	bool res;
	res = true;
	cout << "Time: " << double(endTime - startTime) / CLOCKS_PER_SEC << " seconds" << endl;
	if (hasAnswer) {
		cout << "Desired answer:" << endl;
		cout << "\t" << p1 << endl;
	}
	cout << "Your answer:" << endl;
	cout << "\t" << answer << endl;
	if (hasAnswer) {
		res = answer == p1;
	}
	if (!res) {
		cout << "DOESN'T MATCH!!!!" << endl;
	} else if (double(endTime - startTime) / CLOCKS_PER_SEC >= 2) {
		cout << "FAIL the timeout" << endl;
		res = false;
	} else if (hasAnswer) {
		cout << "Match :-)" << endl;
	} else {
		cout << "OK, but is it right?" << endl;
	}
	cout << "" << endl;
	return res;
}
int main() {
	bool all_right;
	all_right = true;

	string p0;
	int p1;

	{
	// ----- test 0 -----
	p0 = "geese";
	p1 = 2;
	all_right = KawigiEdit_RunTest(0, p0, true, p1) && all_right;
	// ------------------
	}

	{
	// ----- test 1 -----
	p0 = "tattarrattat";
	p1 = 6;
	all_right = KawigiEdit_RunTest(1, p0, true, p1) && all_right;
	// ------------------
	}

	{
	// ----- test 2 -----
	p0 = "www";
	p1 = 0;
	all_right = KawigiEdit_RunTest(2, p0, true, p1) && all_right;
	// ------------------
	}

	{
	// ----- test 3 -----
	p0 = "topcoder";
	p1 = 6;
	all_right = KawigiEdit_RunTest(3, p0, true, p1) && all_right;
	// ------------------
	}

	{
	// ----- test 4 -----
	p0 = "xrepayuyubctwtykrauccnquqfuqvccuaakylwlcjuyhyammag";
	p1 = 43;
	all_right = KawigiEdit_RunTest(4, p0, true, p1) && all_right;
	// ------------------
	}

	if (all_right) {
		cout << "You're a stud (at least on the example cases)!" << endl;
	} else {
		cout << "Some of the test cases had errors." << endl;
	}
	return 0;
}
// END KAWIGIEDIT TESTING
//Powered by KawigiEdit 2.1.8 (beta) modified by pivanof!
<file_sep>/code/SRM589-DIV2/250.cpp
/**
 * The template of Topcoder
 * Author: XadillaX (<EMAIL>)
 */
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <deque>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <ctime>
using namespace std;

#define ZERO(x) (memset(x, 0, sizeof(x)))
#define SIZE(x) ((int)(x.size()))
#define LENGTH(x) ((int)(x.length()))
#define LL long long

/** Segment tree */
#define LC(x) ((x >> 1) + 1)
#define RC(x) ((x >> 1) + 2)

/** Math */
const double pi = acos(-1.0f);
const double eps = 1e-8;

class GooseTattarrattatDiv2
{
public:
    int getmin(string S);
};

int GooseTattarrattatDiv2::getmin(string S)
{
    int maxsame = 0;
    map<char, int> mp;
    for(int i = 0; i < LENGTH(S); i++)
    {
    	mp[S[i]]++;
    	maxsame = max(maxsame, mp[S[i]]);
    }

    return LENGTH(S) - maxsame;
}

<%:testing-code%>
//Powered by KawigiEdit 2.1.8 (beta) modified by pivanof!
<file_sep>/code/SRM589-DIV2/500.cpp
/**
 * The template of Topcoder
 * Author: XadillaX (<EMAIL>)
 */
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <deque>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <ctime>
using namespace std;

#define ZERO(x) (memset(x, 0, sizeof(x)))
#define SIZE(x) ((int)(x.size()))
#define LENGTH(x) ((int)(x.length()))
#define LL long long

/** Segment tree */
#define LC(x) ((x >> 1) + 1)
#define RC(x) ((x >> 1) + 2)

/** Math */
const double pi = acos(-1.0f);
const double eps = 1e-8;

class GearsDiv2
{
public:
    int getmin(string Directions);
};

int GearsDiv2::getmin(string Directions)
{
    int dp[100][2][2];
    for(int i = 0; i < LENGTH(Directions); i++)
    {
    	if(i == 0)
    	{
    		dp[i][0][0] = 1;
    		dp[i][0][1] = 10000000;
    		dp[i][1][1] = 0;
    		dp[i][1][0] = 10000000;
    	}
    	else
    	if(i == 1)
    	{
    		if(Directions[i] == Directions[i - 1])
    		{
    			dp[i][0][1] = 1;
    			dp[i][1][0] = 1;

    			dp[i][0][0] = 10000000;
    			dp[i][1][1] = 10000000;
    		}
    		else
    		{
    			dp[i][0][0] = 2;
    			dp[i][0][1] = 1;
    			dp[i][1][0] = 1;
    			dp[i][1][1] = 0;
    		}
    	}
    	else
    	if(Directions[i] == Directions[i - 1])
    	{
    		dp[i][1][0] = dp[i - 1][0][0];
    		dp[i][1][1] = dp[i - 1][0][1];

    		dp[i][0][0] = dp[i - 1][1][0] + 1;
    		dp[i][0][1] = dp[i - 1][1][1] + 1;
    	}
    	else
    	{
    		dp[i][1][0] = min(dp[i - 1][0][0], dp[i - 1][1][0]);
    		dp[i][1][1] = min(dp[i - 1][0][1], dp[i - 1][1][1]);

    		dp[i][0][0] = min(dp[i - 1][1][0], dp[i - 1][0][0]) + 1;
    		dp[i][0][1] = min(dp[i - 1][1][1], dp[i - 1][1][1]) + 1;
    	}

    	cout << "dp[" << i << "][0][0] = " << dp[i][0][0] << "; ";
    	cout << "dp[" << i << "][1][1] = " << dp[i][1][1] << "; ";
    	cout << "dp[" << i << "][0][1] = " << dp[i][0][1] << "; ";
    	cout << "dp[" << i << "][1][0] = " << dp[i][1][0] << "; ";
    	cout << endl;
    }

    int ans;
    int mi = LENGTH(Directions) - 1;
    if(Directions[mi] == Directions[0])
    {
    	ans = min(dp[mi][0][0], min(dp[mi][1][0], dp[mi][0][1]));
    }
    else
    {
    	ans = min(min(dp[mi][0][0], dp[mi][1][1]), min(dp[mi][0][1], dp[mi][1][0]));
    	//ans = min(dp[mi][0][0], min(dp[mi[1][0], min(dp[mi][0][1], dp[mi][1][1])));
    }

    return ans;
}

<%:testing-code%>
//Powered by KawigiEdit 2.1.8 (beta) modified by pivanof!

languages: Markdown C++

repo_name: cnsuhao/xadillax-topcoder


text:
<file_sep>import React, { useState } from 'react';
import AddUser from './components/User/AddUser';
import UsersList from './components/User/UsersList';

function App() {
  const [usersList, setUsersLists] = useState([]);

  const onAddUsersHandler = (uName, uAge) => {
    setUsersLists((prevUsersList) => {
      return [...prevUsersList, { name: uName, age: uAge, id: Math.random() }];
    });
  };
  return (
    <>
      <AddUser onAddUser={onAddUsersHandler} />;
      <UsersList users={usersList} />
    </>
  );
}

export default App;

branch_name: refs/heads/master

repo_language: JavaScript

repo_name: tauseefanwr/user-app


text:
<file_sep># java-apcompsci
2019-2020 Union HS, NJ // AP Computer Science  // Period 1

repo_language: Markdown

repo_name: isaiah-alv/java-apcompsci


text:
<repo_name>takahiro-hanada/xanadu.reactive-modeling-extensions<file_sep>/Xanadu.ReactiveModelingExtensions/CollectionChangedReactiveAction.cs

namespace Xanadu
{
    public enum CollectionChangedReactiveAction : byte
    {
        None = 0,
        Insert = 1,
        Remove = 2,
        Replace = 3,
    }
}
<file_sep>/Xanadu.ReactiveModelingExtensions.Tests/ReactiveModelingExtensionsTests.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Reactive.Linq;
using Xunit;

namespace Xanadu
{
    public class ReactiveModelingExtensionsTests
    {
        [Fact]
        public void ObservePropertyChangedTest()
        {
            const string newName = "Jack";

            var person = new PersonX();

            var changedPropertyNameList = new List<string>();

            person
                .ObservePropertyChanged()
                .Select(e => e.PropertyName)
                .Subscribe(changedPropertyNameList.Add);

            person.Name = newName;

            Assert.Single(changedPropertyNameList);
            Assert.All(changedPropertyNameList, s => Assert.Equal(nameof(person.Name), s));
        }

        [Fact]
        public void ObserveCollectionChangedTest()
        {
            const string value1 = "1";
            const string value2 = "2";
            const string value3 = "3";

            var values = new ObservableCollection<string>();

            var changedEventArgsList = new List<NotifyCollectionChangedEventArgs>();

            values
                .ObserveCollectionChanged()
                .Subscribe(changedEventArgsList.Add);

            values.Add(value1);
            values.Add(value2);
            values.Move(1, 0);
            values[1] = value3;
            values.Remove(value3);
            values.Clear();

            Assert.Equal(6, changedEventArgsList.Count);
            Assert.Equal(NotifyCollectionChangedAction.Add, changedEventArgsList[0].Action);
            Assert.Equal(NotifyCollectionChangedAction.Add, changedEventArgsList[1].Action);
            Assert.Equal(NotifyCollectionChangedAction.Move, changedEventArgsList[2].Action);
            Assert.Equal(NotifyCollectionChangedAction.Replace, changedEventArgsList[3].Action);
            Assert.Equal(NotifyCollectionChangedAction.Remove, changedEventArgsList[4].Action);
            Assert.Equal(NotifyCollectionChangedAction.Reset, changedEventArgsList[5].Action);
        }

        [Fact]
        public void ObservePropertyTest()
        {
            const string name0 = null;
            const string name1 = "Jack";
            const string name2 = "John";

            var person = new PersonX() { Name = name0 };

            var propertyValueList = new List<string>();

            person
                .ObserveProperty(o => o.Name)
                .Subscribe(propertyValueList.Add);
            person.Name = name1;
            person.Name = name2;
            person.Name = name2;
            person.Name = name0;

            Assert.Equal(4, propertyValueList.Count);
            Assert.Equal(name0, propertyValueList[0]);
            Assert.Equal(name1, propertyValueList[1]);
            Assert.Equal(name2, propertyValueList[2]);
            Assert.Equal(name0, propertyValueList[3]);
        }

        [Fact]
        public void ObserveCollectionChangedReactiveTest()
        {
            const string value1 = "1";
            const string value2 = "2";
            const string value3 = "3";

            var values = new ObservableCollection<string>();

            var argsList = new List<CollectionChangedReactiveArgs<string>>();

            values
                .ObserveCollectionChangedReactive()
                .Subscribe(argsList.Add);

            values.Add(value1);
            values.Add(value2);
            values.Move(1, 0);
            values[1] = value3;
            values.Remove(value3);
            values.Clear();

            Assert.Equal(7, argsList.Count);
            Assert.Equal(CollectionChangedReactiveAction.Insert, argsList[0].Action);
            Assert.Equal(CollectionChangedReactiveAction.Insert, argsList[1].Action);
            Assert.Equal(CollectionChangedReactiveAction.Remove, argsList[2].Action);
            Assert.Equal(CollectionChangedReactiveAction.Insert, argsList[3].Action);
            Assert.Equal(CollectionChangedReactiveAction.Replace, argsList[4].Action);
            Assert.Equal(CollectionChangedReactiveAction.Remove, argsList[5].Action);
            Assert.Equal(CollectionChangedReactiveAction.Remove, argsList[6].Action);
        }

        [Fact]
        public void ObserveCollectionChangedReactiveTestForBindingLIst()
        {
            const string value1 = "1";
            const string value2 = "2";
            const string value3 = "3";
            const string value4 = "4";

            var values = new BindingList<string>();

            var argsList = new List<CollectionChangedReactiveArgs<string>>();

            values
                .ObserveCollectionChangedReactive()
                .Subscribe(argsList.Add);

            values.Add(value1);
            values.Add(value2);
            values[1] = value3;
            values.Remove(value3);
            values.Add(value4);
            values.Clear();

            Assert.Equal(7, argsList.Count);

            Assert.Equal(CollectionChangedReactiveAction.Insert, argsList[0].Action);
            Assert.Equal(value1, argsList[0].NewItem);

            Assert.Equal(CollectionChangedReactiveAction.Insert, argsList[1].Action);
            Assert.Equal(value2, argsList[1].NewItem);

            Assert.Equal(CollectionChangedReactiveAction.Replace, argsList[2].Action);
            Assert.Equal(value2, argsList[2].OldItem);
            Assert.Equal(value3, argsList[2].NewItem);

            Assert.Equal(CollectionChangedReactiveAction.Remove, argsList[3].Action);
            Assert.Equal(value3, argsList[3].OldItem);

            Assert.Equal(CollectionChangedReactiveAction.Insert, argsList[4].Action);
            Assert.Equal(value4, argsList[4].NewItem);

            Assert.Equal(CollectionChangedReactiveAction.Remove, argsList[5].Action);
            Assert.Equal(value4, argsList[5].OldItem);

            Assert.Equal(CollectionChangedReactiveAction.Remove, argsList[6].Action);
            Assert.Equal(value1, argsList[6].OldItem);
        }
    }
}
<file_sep>/Xanadu.ReactiveModelingExtensions/ReactiveModelingExtensions.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Reactive;
using System.Reactive.Linq;

namespace Xanadu
{
    public static partial class ReactiveModelingExtensions
    {
        public static ObservableCollection<T> ToObservableCollection<T>(this IEnumerable<T> collection) => new ObservableCollection<T>(collection);

        public static ReadOnlyObservableCollection<T> ToReadOnlyObservableCollection<T>(this ObservableCollection<T> list) => new ReadOnlyObservableCollection<T>(list);

        public static T AddTo<T>(this T item, ICollection<IDisposable> collection) where T : IDisposable
        {
            if (collection == null) throw new ArgumentNullException(nameof(collection));

            collection.Add(item);

            return item;
        }

        public static T RemoveFrom<T>(this T item, ICollection<IDisposable> collection) where T : IDisposable
        {
            if (collection == null) throw new ArgumentNullException(nameof(collection));

            collection.Remove(item);

            return item;
        }

        public static IObservable<PropertyChangedEventArgs> ObservePropertyChanged(this INotifyPropertyChanged target)
        {
            if (target == null) throw new ArgumentNullException(nameof(target));

            return Observable.FromEvent<PropertyChangedEventHandler, PropertyChangedEventArgs>(
                h => (sender, e) => h(e),
                h => target.PropertyChanged += h,
                h => target.PropertyChanged -= h
                );
        }

        public static IObservable<Unit> ObservePropertyChanged<T, TProperty>(this T target, Expression<Func<T, TProperty>> propertySelector)
            where T : INotifyPropertyChanged
        {
            var propertyChanged = target.ObservePropertyChanged();

            if (propertySelector == null) throw new ArgumentNullException(nameof(propertySelector));

            var propertyName = ((MemberExpression)propertySelector.Body).Member.Name;

            return propertyChanged.Where(e => e.PropertyName == propertyName).Select(_ => Unit.Default);
        }

        public static IObservable<NotifyCollectionChangedEventArgs> ObserveCollectionChanged(this INotifyCollectionChanged target)
        {
            if (target == null) throw new ArgumentNullException(nameof(target));

            return Observable.FromEvent<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
                h => (sender, e) => h(e),
                h => target.CollectionChanged += h,
                h => target.CollectionChanged -= h
                );
        }

        // Not published yet.
        static IObservable<ListChangedEventArgs> ObserveListChanged(this IBindingList target)
        {
            if (target == null) throw new ArgumentNullException(nameof(target));

            return Observable.FromEvent<ListChangedEventHandler, ListChangedEventArgs>(
                h => (sender, e) => h(e),
                h => target.ListChanged += h,
                h => target.ListChanged -= h
                );
        }

        public static IObservable<TProperty> ObserveProperty<T, TProperty>(this T target, Expression<Func<T, TProperty>> propertySelector)
            where T : INotifyPropertyChanged
        {
            var propertyChanged = target.ObservePropertyChanged(propertySelector);

            var getter = propertySelector.Compile();

            return propertyChanged.Select(_ => getter(target)).StartWith(getter(target));
        }

        // public static IObservable<CollectionChangedReactiveArgs<T>> ObserveCollectionChangedReactive<T, TCollection>(this TCollection target)
        //     where TCollection : IEnumerable<T>, INotifyCollectionChanged
        public static IObservable<CollectionChangedReactiveArgs<T>> ObserveCollectionChangedReactive<T>(this IEnumerable<T> target)
        {
            if (target == null)
                throw new ArgumentNullException(nameof(target));

            else if (target is INotifyCollectionChanged notifyCollectionChanged)
                return ObserveCollectionChangedReactive(target, notifyCollectionChanged);

            else if (target is IBindingList bindingList)
                return ObserveCollectionChangedReactive(target, bindingList);

            else
                throw new ArgumentOutOfRangeException(nameof(target));
        }

        static IObservable<CollectionChangedReactiveArgs<T>> ObserveCollectionChangedReactive<T>(IEnumerable<T> ts, INotifyCollectionChanged ntc) => ntc
            .ObserveCollectionChanged()
            .Select(e =>
            {
                var buffer = ts.ToArray();

                var infos = default(CollectionChangedReactiveArgs<T>[]);

                switch (e.Action)
                {
                    case NotifyCollectionChangedAction.Add:

                        infos = Enumerable
                            .Range(e.NewStartingIndex, e.NewItems.Count)
                            .Select((sourceIndex, changedIndex) => new CollectionChangedReactiveArgs<T>(CollectionChangedReactiveAction.Insert, sourceIndex, (T)e.NewItems[changedIndex]))
                            .ToArray();
                        break;

                    case NotifyCollectionChangedAction.Remove:

                        infos = Enumerable
                            .Range(e.OldStartingIndex, e.OldItems.Count)
                            .Select((sourceIndex, changedIndex) => new CollectionChangedReactiveArgs<T>(CollectionChangedReactiveAction.Remove, sourceIndex, (T)e.OldItems[changedIndex]))
                            .Reverse()
                            .ToArray();
                        break;

                    case NotifyCollectionChangedAction.Replace:
                        {
                            var olds = Enumerable
                                .Range(e.OldStartingIndex, e.OldItems.Count)
                                .Select((index, changedItemsIndex) => new { index, item = (T)e.OldItems[changedItemsIndex] });

                            var news = Enumerable
                                .Range(e.NewStartingIndex, e.NewItems.Count)
                                .Select((index, changedItemsIndex) => new { index, item = (T)e.NewItems[changedItemsIndex] });

                            infos = olds.Join(news, o => o.index, n => n.index, (o, n) => new { o.index, oldItem = o.item, newItem = n.item })
                                .Select(on => new CollectionChangedReactiveArgs<T>(CollectionChangedReactiveAction.Replace, on.index, (T)on.oldItem, (T)on.newItem))
                                .ToArray();

                            break;
                        }
                    case NotifyCollectionChangedAction.Move:
                        {
                            var olds = Enumerable
                                .Range(e.OldStartingIndex, e.OldItems.Count)
                                .Select((index, changedItemsIndex) => new { index, changedItemsIndex, item = (T)e.OldItems[changedItemsIndex] });

                            var news = Enumerable
                                .Range(e.NewStartingIndex, e.NewItems.Count)
                                .Select((index, changedItemsIndex) => new { index, changedItemsIndex, item = (T)e.NewItems[changedItemsIndex] });

                            var q =
                                from o in olds
                                join n in news on o.changedItemsIndex equals n.changedItemsIndex
                                select new[]
                                {
                                    new CollectionChangedReactiveArgs<T>(CollectionChangedReactiveAction.Remove, o.index, o.item),
                                    new CollectionChangedReactiveArgs<T>(CollectionChangedReactiveAction.Insert, n.index, n.item),
                                };

                            infos = q.SelectMany(array => array).ToArray();

                            break;
                        }
                }

                return new { buffer, infos };
            })
            .StartWith(new { buffer = ts.ToArray(), infos = default(CollectionChangedReactiveArgs<T>[]) })
            .Scan((o, n) => new
            {
                n.buffer,
                infos = n.infos ?? o.buffer.Select((item, index) => new CollectionChangedReactiveArgs<T>(CollectionChangedReactiveAction.Remove, index, item)).Reverse().ToArray()
            })
            .Select(o => o.infos ?? new CollectionChangedReactiveArgs<T>[0])
            .SelectMany(o => o.ToObservable())
            ;

        static IObservable<CollectionChangedReactiveArgs<T>> ObserveCollectionChangedReactive<T>(IEnumerable<T> ts, IBindingList bl) => bl
            .ObserveListChanged()
            .Select(args => new { args, buffer = ts.ToArray(), bufferPrevious = default(T[])})
            .StartWith(new { args = default(ListChangedEventArgs), buffer = ts.ToArray(), bufferPrevious = default(T[]) })
            .Scan((previous, current) => new { current.args, current.buffer, bufferPrevious = previous.buffer })
            .Skip(1)
            .Select(o =>
            {
                switch (o.args.ListChangedType)
                {
                    case ListChangedType.ItemAdded:
                        return new[]
                        {
                            new CollectionChangedReactiveArgs<T>(CollectionChangedReactiveAction.Insert, o.args.NewIndex  , o.buffer[o.args.NewIndex] )
                        };

                    case ListChangedType.ItemDeleted:
                        return new[]
                        {
                            new CollectionChangedReactiveArgs<T>(CollectionChangedReactiveAction.Remove, o.args.NewIndex, o.bufferPrevious[o.args.NewIndex])
                        };

                    case ListChangedType.ItemChanged:
                        return new[]
                        {
                            new CollectionChangedReactiveArgs<T>(CollectionChangedReactiveAction.Replace
                                , o.args.NewIndex
                                , o.bufferPrevious[o.args.NewIndex]
                                , o.buffer[o.args.NewIndex]
                                )
                        };

                    case ListChangedType.ItemMoved:
                        return new[]
                        {
                            new CollectionChangedReactiveArgs<T>(CollectionChangedReactiveAction.Remove
                                , o.args.OldIndex
                                , o.bufferPrevious[o.args.OldIndex]
                                ),
                            new CollectionChangedReactiveArgs<T>(CollectionChangedReactiveAction.Insert
                                , o.args.NewIndex
                                , o.buffer[o.args.NewIndex]
                                ),
                        };

                    case ListChangedType.Reset:
                        return o.bufferPrevious.Select((item, index) => new CollectionChangedReactiveArgs<T>(CollectionChangedReactiveAction.Remove, index, item)).Reverse().ToArray();

                    default:
                        return new CollectionChangedReactiveArgs<T>[0];
                }
            })
            .SelectMany(o => o.ToObservable())
            .Where(o => o != null);
    }
}
<file_sep>/Xanadu.ReactiveModelingExtensions.Tests/PersonX.cs
using System.ComponentModel;

namespace Xanadu
{
    sealed class PersonX : Person, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public override string Name
        {
            get => base.Name;
            set
            {
                if (base.Name != value)
                {
                    base.Name = value;

                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Name)));
                }
            }
        }
    }
}
<file_sep>/Xanadu.ReactiveModelingExtensions/CollectionChangedReactiveArgs.cs
using System;

namespace Xanadu
{
    public sealed class CollectionChangedReactiveArgs<T>
    {
        public CollectionChangedReactiveAction Action { get; }

        public int Index { get; }

        public T OldItem { get; }

        public T NewItem { get; }

        CollectionChangedReactiveArgs(CollectionChangedReactiveAction action, int index)
        {
            if (action == CollectionChangedReactiveAction.None) throw new ArgumentOutOfRangeException(nameof(action));

            if (index < 0) throw new ArgumentOutOfRangeException(nameof(index));

            Action = action;

            Index = index;
        }

        public CollectionChangedReactiveArgs(CollectionChangedReactiveAction action, int index, T item) : this(action, index)
        {
            switch (action)
            {
                case CollectionChangedReactiveAction.Insert:

                    NewItem = item;

                    break;

                case CollectionChangedReactiveAction.Remove:

                    OldItem = item;

                    break;

                default:

                    throw new ArgumentOutOfRangeException(nameof(action));
            }
        }

        public CollectionChangedReactiveArgs(CollectionChangedReactiveAction action, int index, T oldItem, T newItem) : this(action, index)
        {
            if (action == CollectionChangedReactiveAction.Replace)
            {
                OldItem = oldItem;

                NewItem = newItem;
            }
            else
            {
                throw new ArgumentOutOfRangeException(nameof(action));
            }
        }
    }
}

repo_language: C#


text:
<repo_name>RenkoT97/Projekt2017<file_sep>/README.md
# ProjektUVP: Kenken
Projektno delo za predmet Uvod v programiranje 1. letnika finančne matematike
<file_sep>/program.py
import tkinter as tk
import random
import sys
import os

def pretvori_dat_v_sez(ime_dat):
    with open(ime_dat) as dat:
        datoteka = dat.readlines()
        seznam = [[[crka.strip() for crka in crke.split(',') if crka.strip() not in [" ", ","]] for crke in vrstica.split("~")[1:-1] if vrstica.strip()] for vrstica in datoteka]
        return seznam

seznam1 = pretvori_dat_v_sez('Resitve.txt')
seznam2 = pretvori_dat_v_sez('barve_polj.txt')
seznam31 = pretvori_dat_v_sez('operacije.txt')

def zbrisi_x(seznam):
    sez = []
    for element in seznam:
        sez.append(element.replace('x', ''))
    return sez

def spremeni(seznam):
    sez = []
    for podseznam in seznam:
        sez.append(zbrisi_x(podseznam))
    return sez

def spremeni_seznam(seznam):
    sez = []
    for podseznam in seznam:
        sez.append(spremeni(podseznam))
    return sez

seznam3 = spremeni_seznam(seznam31)

st_kenkena = random.randint(0, 9)

barve = {'A': 'deep sky blue', 'B': 'yellow', 'C': 'red2', 'D': 'forest green', 'E': 'tan1', \
'F': 'DarkOrange1', 'G': 'chartreuse2', 'H': 'deep pink', 'I': 'steel blue', 'J': 'plum3', \
'K': 'SlateBlue3', 'L': 'medium sea green', 'M': 'goldenrod', 'N': 'OliveDrab2', 'O': 'DarkOrchid3'}

okno = tk.Tk()

seznam_vhodov = []
for i in range(6):
    podsez = []
    for j in range(6):
        vhod = tk.Entry(okno, bg = barve[seznam2[st_kenkena][i][j]])
        vhod.insert(0, seznam3[st_kenkena][i][j] + '           ')
        vhod.grid(row = i + 1, column = j, ipady = 40)
        podsez.append(vhod)
    seznam_vhodov.append(podsez)

def resitve():
    sez = []
    seznam = seznam1[st_kenkena]
    for element in seznam:
        for podelement in element:
            sez.append(podelement)
    return sez

def preberi_resitve():
    pridobljene_resitve = []
    for i in range(6):
        podsez = []
        for j in range(6):
            podsez.append(seznam_vhodov[i][j].get())
        pridobljene_resitve.append(podsez)
    nov_sez = []
    for element in pridobljene_resitve:
        for podelement in element:
            if '+' in podelement or '-' in podelement or '*' in podelement or ':' in podelement:
                for znak in podelement:
                    if znak in '*:+-':
                        mesto = podelement.index(znak)
                        nov = podelement[(mesto + 1):]
                        nov_sez.append(nov.replace(' ', ''))
            else:
                nov_sez.append(podelement.replace(' ', ''))
    return nov_sez

def preveri_resitve():
    if preberi_resitve() == resitve():
        return 'Čestitke! Pravilno ste izpolnili kenken!'
    else:
        return 'Vaša rešitev je žal napačna.'

def okno_preveri_resitve():
    okno2 = tk.Tk()
    resitve = tk.Label(okno2, text = preveri_resitve(), bg = 'papayawhip', font = 'slant')
    resitve.pack()
    okno2.mainloop()

gumb_za_preverjanje_resitev = tk.Button(okno, text = 'Preveri rešitve', command = okno_preveri_resitve, cursor = 'hand2', activebackground = 'wheat', bg = 'papayawhip', width = '16')
gumb_za_preverjanje_resitev.grid(row = 0, column = 1)
gumb_za_preverjanje_resitev.pack

besedilo_navodila = 'Kenken je matematična uganka, ki jo je leta 2004 razvil japonski učitelj Tetsuya Miyamoto. \n Rešuje se ga tako, da se v vsako vrstico in stolpec dolžine n napiše prvih n različnih naravnih \n števil, v vsako polje iste barve pa taka števila, da iz njih s pripadajočo operacijo dobimo \n rezultat, napisan v polju.'

def povej_mi_navodila():
    okno3 = tk.Tk()
    navodila = tk.Label(okno3, text = besedilo_navodila, bg = 'papayawhip', font = 'slant', justify = 'left')
    navodila.pack()
    okno3.mainloop()

gumb_za_navodila = tk.Button(okno, text = 'Povej mi navodila', command = povej_mi_navodila, cursor ='hand2', activebackground = 'wheat', bg = 'papayawhip', width = '16')
gumb_za_navodila.grid(row = 0, column = 0)
gumb_za_navodila.pack

def zacni_še_enkrat():
    python = sys.executable
    os.execl(python, python, *sys.argv)

gumb_za_nov_kenken = tk.Button(okno, text = 'Nov kenken', command = zacni_še_enkrat, cursor = 'hand2', activebackground = 'wheat', bg = 'papayawhip', width = '16')
gumb_za_nov_kenken.grid(row = 0, column = 2)
gumb_za_nov_kenken.pack

def izhod():
    okno.destroy()

gumb_za_izhod = tk.Button(okno, text = 'Izhod', command = izhod, cursor = 'hand2', activebackground = 'wheat', bg = 'papayawhip', width = '16')
gumb_za_izhod.grid(row = 0, column = 3)
gumb_za_izhod.pack

okno.mainloop()

languages: Markdown Python


text:
<file_sep>function enviarformulario() {

    alert("Enviado con Exito, espera pronto tu respuesta")

}

function reserva() {

    alert("Reserva enviada, espera tu confirmación en el correo")
}<file_sep><!DOCTYPE html>

    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mulato´s Bistro</title>
    <link rel="stylesheet" href="css/encabezado.css">
    <link rel="stylesheet" href="css/contenido-index.css">
    <link rel="stylesheet" href="css/footer.css">

        <input type="checkbox" id="boton_menu">

 Inicio

 Nuestros Productos

 Nuestro Menú

 Reserva con Nosotros

 Contacto

 ARTESANOS DE LA COCINA

                Mulato´s Bistro es un restaurante caracterizado por su cocina artesanal, identificandose mas al estilo
                texano y mexicano logrando asi realzar los sabores de ambos para lograr un intenso y delicioso sabor en
                sus platillos.

¿Que esperas para vivir la experiencia Mulato´s Bistro?

                <form action="">

 ¿Tienes alguna pregunta o comentario?

                     aqui te respondemos lo mas pronto posible

                    <input type="name" placeholder="<NAME>" required>
                    <input type="email" placeholder="<EMAIL>" required>
                    <textarea name="comentarios" id="textarea" placeholder="deja tu pregunta o comentario aqui" ></textarea>

                    <input type="submit" id="boton" value="Enviar" onclick="enviarformulario()">
                </form>

¡Contactanos!

 ©COPYRIGHT2021 MULATO´S BISTRO, TODOS LOS DERECHOS RESERVADOS
 Pagina web y estrategia por: <NAME>

languages: HTML JavaScript

repo_language: HTML


text:
<repo_name>kimjiwook/kakao_ios_test<file_sep>/iOS_Kimjiwook/iOS_Kimjiwook/ViewController/DetailViewController.h
//
//  DetailViewController.h
//  iOS_Kimjiwook
//
//  Created by kimjiwook on 2018. 4. 12..
//  Copyright © 2018년 kimjiwook. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "RootViewController.h"

@interface DetailViewController : RootViewController
@property (nonatomic, strong) NSString *navigationTitle; // 타이틀 정보.
@property (nonatomic, strong) NSString *detailUrl; // 상세Url 정보.
@end
<file_sep>/iOS_Kimjiwook/iOS_Kimjiwook/Protocol/ProtocolList.h
//
//  ProtocolList.h
//  iOS_Kimjiwook
//
//  Created by kimjiwook on 2018. 4. 11..
//  Copyright © 2018년 kimjiwook. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface ProtocolList : NSObject
/// 1. 최초 HTML Parsing을 통하여 리스트 구해오기.
- (void)getImageArray:(void (^)(id ob))complete :(void (^)(NSError *error))fail;
/// 2. 상세화면 진입시 HTML Parsing을 통해 데이터 가져오기.
- (void)getDetailVM:(NSString *)stringUrl :(void (^)(id ob))complete :(void (^)(NSError *error))fail;
@end
<file_sep>/iOS_Kimjiwook/iOS_Kimjiwook/ViewController/MainViewController.h
//
//  MainViewController.h
//  iOS_Kimjiwook
//
//  Created by kimjiwook on 2018. 4. 11..
//  Copyright © 2018년 kimjiwook. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "RootViewController.h"

@interface MainViewController : RootViewController

@end
<file_sep>/iOS_Kimjiwook/iOS_Kimjiwook/Util/ImageCache.m
//
//  ImageCache.m
//  iOS_Kimjiwook
//
//  Created by kimjiwook on 2018. 4. 11..
//  Copyright © 2018년 kimjiwook. All rights reserved.
//

#import "ImageCache.h"
#import <CommonCrypto/CommonDigest.h>

@interface ImageCache() {
//    NSMutableDictionary *cache;
}

@end

@implementation ImageCache

/**
 싱글턴을 이용한 객체 생성.
 @return self
 */
+ (ImageCache *)instance {
    static ImageCache *imageCache = nil;
    static dispatch_once_t onceToken;

    if (imageCache == nil) {
        // 최초 한번만 실행했는지 판단.
        dispatch_once(&onceToken, ^{
            imageCache = [[ImageCache alloc] init];
        });
    }
    return imageCache;
}

- (id)init {
    self = [super init];

    if (self) {
        // url 캐시 설정
        NSInteger byte = 1024 * 1024;
        // 메모리 : 10MB, 디스크 : 100MB (메모리 캐쉬는 ViewModel 에서 따로 할 예정)
        NSURLCache *urlCache = [[NSURLCache alloc] initWithMemoryCapacity:10 * byte diskCapacity:100 * byte diskPath:nil];
        [NSURLCache setSharedURLCache:urlCache];
    }

    return self;
}

#pragma mark- Document 관련.

/**
 로컬에 저장되어 있는 이미지 파일가져오기.

 @param stringUrl 이미지 URL
 @return UIImage
 */
- (UIImage *)getDocumentImageUrl:(NSString *)stringUrl {
    // NSURL 변환.
    NSURL *url = [NSURL URLWithString:stringUrl];

    UIImage *image = nil;
    if (url != nil) {
        NSString *key = [self md5:stringUrl];
        UIImage *cachedImage = [self getDocumentCache:key];

        if (cachedImage != nil) {
            image = cachedImage;
        }
    }
    return image;
}

/**
 로컬에 저장한다.
 @param stringUrl 이미지 URL
 @param image UIImage
 */
- (void)setDocumentImageUrl:(NSString *)stringUrl image:(UIImage *)image {
    NSString *key = [self md5:stringUrl];
    // 디스크 캐시에 추가
    [self setDocumentCache:image withKey:key];
}

- (UIImage *)getDocumentCache:(NSString *)key {
    // 경로 추출.
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docPath = [paths firstObject];
    NSString *path = [NSString stringWithFormat:@"%@/%@", docPath, key];

    // 불러오기.
    return [[UIImage alloc] initWithContentsOfFile:path];
}

- (void)setDocumentCache:(UIImage *)image withKey:(NSString *)key {
    // 경로 추출.
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docPath = [paths firstObject];
    NSString *path = [NSString stringWithFormat:@"%@/%@", docPath, key];

    // 저장
    [UIImagePNGRepresentation(image) writeToFile:path atomically:YES];
}

#pragma mark- MD5를 통한 URL 변환.
// url을 사용해서 md5 해시 문자열 생성
-(NSString*)md5:(NSString *)str {
    const char *cStr = [str UTF8String];
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5( cStr, strlen(cStr), result);
    NSMutableString *string = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
        [string appendFormat:@"%02X",result[i]];
    return string;
}

@end
<file_sep>/iOS_Kimjiwook/iOS_Kimjiwook/Util/ImageCache.h
//
//  ImageCache.h
//  iOS_Kimjiwook
//
//  Created by kimjiwook on 2018. 4. 11..
//  Copyright © 2018년 kimjiwook. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface ImageCache : NSObject
// 싱글턴 객체 생성.
+ (ImageCache *)instance;

//
- (void)setDocumentImageUrl:(NSString *)stringUrl image:(UIImage *)image;
- (UIImage *)getDocumentImageUrl:(NSString *)stringUrl;
@end
<file_sep>/iOS_Kimjiwook/iOS_Kimjiwook/ViewController/MainTableViewCell.m
//
//  MainTableViewCell.m
//  iOS_Kimjiwook
//
//  Created by JW_Macbook on 2018. 4. 11..
//  Copyright © 2018년 kimjiwook. All rights reserved.
//

#import "MainTableViewCell.h"

@interface MainTableViewCell() {
    AFHTTPSessionManager *manager;
}
@end

@implementation MainTableViewCell

- (void)awakeFromNib {
    [super awakeFromNib];
    // 네트워크 생성.
    manager = [AFHTTPSessionManager manager];
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

/**
 Cell 꾸며주는 부분

 @param vm
 @param indexPath
 */
- (void)configuration:(ViewModel *)vm indexPath:(NSIndexPath *)indexPath {
    // 만약에 데이터를 받고있는게 있다면 취소해준다.
    [_imgView.associatedObject cancel];

    // Cell 꾸미기.
    _lbTitle.text = vm.caption;

    // 1. 이미지 다운로드 URL
    NSString *imageUrl = [NSString stringWithFormat:@"%@%@",BASE_URL,vm.thumImageURL];
    _imgView.image = [UIImage imageNamed:@"noimage"]; // 디폴트 이미지
    // 메모리 캐시 점검.
    if (vm.thumImage) {
        _imgView.image = vm.thumImage;
        [[ImageCache instance] setDocumentImageUrl:imageUrl image:vm.thumImage]; // 도큐멘트 저장.
    } else {
        // 도큐멘트 점검.
        UIImage *documentCachedImage = [[ImageCache instance] getDocumentImageUrl:imageUrl];
        if (documentCachedImage) {
            _imgView.image = documentCachedImage;
            vm.thumImage = documentCachedImage; // 메모리 저장.
        } else {
            // 다운로드 로직.
            _imgView.associatedObject =
            [manager GET:imageUrl parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

                self->_imgView.alpha = 0.0f;
                self->_imgView.image = [UIImage imageWithData:(NSData *)responseObject];
                vm.thumImage = self->_imgView.image;
                // #. 메모리, 도큐멘트 저장 로직.
                [UIView animateWithDuration:0.7 animations:^{
                    self->_imgView.alpha = 1.0f;
                }];
                [[ImageCache instance] setDocumentImageUrl:imageUrl image:vm.thumImage];

            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                NSLog(@"%ld, %@",indexPath.row, error);
            }];
        }
    }
}

@end
<file_sep>/iOS_Kimjiwook/iOS_Kimjiwook/ViewController/DetailViewController.m
//
//  DetailViewController.m
//  iOS_Kimjiwook
//
//  Created by kimjiwook on 2018. 4. 12..
//  Copyright © 2018년 kimjiwook. All rights reserved.
//

#import "DetailViewController.h"
#import "ViewModel.h"

@interface DetailViewController () {
    DetailViewModel *detailVM;
    AFHTTPSessionManager *manager;
}
@property (weak, nonatomic) IBOutlet UIImageView *imageView; // 메인 이미지.
@property (weak, nonatomic) IBOutlet UILabel *lbCaption; // 설명글.
@end

@implementation DetailViewController

#pragma mark - #. 기본적인 사항들.

/**
 초기화와 기본적인 셋팅을 맞는 부분.
 */
- (void)initData {
    self.protocolList = [[ProtocolList alloc] init];
    // 네트워크 생성.
    manager = [AFHTTPSessionManager manager];
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];

    [self setNavigation];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    [self initData];
    [self requestHTML];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/**
 네비게이션 정보.
 */
- (void)setNavigation {
    self.title = @"iOS_김지욱";
    if (_navigationTitle) {
        self.title = _navigationTitle;
    }

    [self.navigationController.navigationBar setBarTintColor:[UIColor colorWithRed:0.31 green:0.25 blue:0.21 alpha:1.0f]];
    [self.navigationController.navigationBar setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys:
                                                                      [UIColor whiteColor], NSForegroundColorAttributeName
                                                                      , nil]];
    [self.navigationController.navigationBar setTintColor:[UIColor whiteColor]];
}

/**
 HTML ParserData 호출 후 뿌려주는 부분.
 */
- (void)requestHTML {
    [self startLodingView];
    NSString *stringUrl = [NSString stringWithFormat:@"%@%@", BASE_URL, _detailUrl];
    [self.protocolList getDetailVM:stringUrl :^(id ob) {
        self->detailVM = (DetailViewModel *)ob;
        [self reloadDetailData];
    } :^(NSError *error) {
        NSLog(@"error : %@",error);
        [self stopLodingView];
    }];
}

- (void)reloadDetailData {
    if (!detailVM) {
        [self stopLodingView];
        return;
    }

    // 1. 이미지 영역 부분.
    if (detailVM.detailImage) {
        self.imageView.image = detailVM.detailImage;
        [self stopLodingView];
    } else {
        NSString *stringUrl = [NSString stringWithFormat:@"%@%@", BASE_URL, _detailUrl];
        UIImage *documentCachedImage = [[ImageCache instance] getDocumentImageUrl:stringUrl];
        if (documentCachedImage) {
            self.imageView.image = documentCachedImage;
            detailVM.detailImage = documentCachedImage; // 메모리 저장.
            [self stopLodingView];
        } else {
            NSString *imageUrl = [NSString stringWithFormat:@"%@%@",BASE_URL,detailVM.imageURL];
            [manager GET:imageUrl parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

                self.imageView.image = [UIImage imageWithData:(NSData *)responseObject];
                // #. 메모리, 도큐멘트 저장 로직.
                self->detailVM.detailImage = self.imageView.image;
                [[ImageCache instance] setDocumentImageUrl:imageUrl image:self->detailVM.detailImage];
                [self stopLodingView];
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                [self stopLodingView];
                NSLog(@"%@",error);
            }];
        }
    }

    // 2. 설명 글 부분.
    self.lbCaption.text = detailVM.caption;
}
@end
<file_sep>/iOS_Kimjiwook/iOS_Kimjiwook/Protocol/ProtocolList.m
//
//  ProtocolList.m
//  iOS_Kimjiwook
//
//  Created by kimjiwook on 2018. 4. 11..
//  Copyright © 2018년 kimjiwook. All rights reserved.
//

#import "ProtocolList.h"
#import "ViewModel.h"

@implementation ProtocolList

/**
 HTML 분석하기. 최초
 */
- (void)getImageArray:(void (^)(id ob))complete :(void (^)(NSError *error))fail {
    // URL 정보.
    NSString *url = [NSString stringWithFormat:@"%@%@",BASE_URL,BASE_URL_GET_PARAM];

    // 네트워크 통신 준비.
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];

    [manager GET:url parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSData *data = (NSData *)responseObject;
        NSString *html = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

        // HTML Parser
        HTMLDocument *doc = [HTMLDocument documentWithString:html];
        NSArray *elements = [doc nodesMatchingSelector:@"div"];

        NSMutableArray *listArray = [[NSMutableArray alloc] init];
        for (HTMLElement *element in elements) {
            if ([[element attributes] objectForKey:@"class"]) {
                // 전체 가져오는 부분 (리스트 갯수가 맞음.)
                NSString *class = [[element attributes] objectForKey:@"class"];
                // 두가지 타입의 id를 가지고 있는 아이들을 리스트로 뺀다.
                if ([class isEqualToString:@"gallery-item-group lastitemrepeater"] ||
                    [class isEqualToString:@"gallery-item-group exitemrepeater"]) {

                    // 객체 생성.
                    ViewModel *vm = [[ViewModel alloc] init];

                    // 내부를 반복 돌려 확인하기.
                    for (HTMLElement *childElement in [element childElementNodes]) {

                        // 1. 상세 URL
                        if ([@"" isEqualToString:vm.detailURL]) {
                            vm.detailURL = [[childElement attributes] objectForKey:@"href"];
                        }

                        // 2. 썸네일 이미지, 설명글
                        for (HTMLElement *srcElement in [childElement childElementNodes]) {
                            if ([@"" isEqualToString:vm.thumImageURL]) {
                                vm.thumImageURL = [[srcElement attributes] objectForKey:@"src"];
                                break;
                            }
                        }
                    }

                    // 3. 설명글 (앞,뒤 공백만 제거)
                    if ([@"" isEqualToString:vm.caption]) {
                        NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
                        vm.caption = [element.textContent stringByTrimmingCharactersInSet:whitespace];
                    }

                    [listArray addObject:vm];
                }
            }
        }
        // 완료.
        complete(listArray);

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        // 에러
        fail(error);
    }];
}

/**
 상세화면 HTML 파싱 후 데이터 진행.

 @param stringUrl
 @param complete
 @param fail
 */
- (void)getDetailVM:(NSString *)stringUrl :(void (^)(id ob))complete :(void (^)(NSError *error))fail {
    // 네트워크 통신 준비.
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer = [AFHTTPRequestSerializer serializer];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];

    [manager GET:stringUrl parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSData *data = (NSData *)responseObject;
        NSString *html = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

        // HTML Parser
        HTMLDocument *doc = [HTMLDocument documentWithString:html];
        NSArray *elements = [doc nodesMatchingSelector:@"div"];
        // ViewModel 객체 생성.
        DetailViewModel *vm = [[DetailViewModel alloc] init];

        for (HTMLElement *element in elements) {
            if ([[element attributes] objectForKey:@"class"]) {

                NSString *class = [[element attributes] objectForKey:@"class"];
                // 두가지 타입의 id를 가지고 있는 아이들을 리스트로 뺀다.
                if ([class isEqualToString:@"innerImageArea"] ||
                    [class isEqualToString:@"proddetails"]) {

                    NSLog(@"");
                    // 내부를 반복 돌려 확인하기.
                    for (HTMLElement *childElement in [element childElementNodes]) {
                        // 1. 상세 이미지 URL
                        if ([@"" isEqualToString:vm.imageURL]) {
                            vm.imageURL = [[childElement attributes] objectForKey:@"src"];
                        }

                        // 상세 정보. P 태그정보만 가져온다.
                        if ([@"p" isEqualToString:childElement.tagName]) {
                            NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
                            NSString *content = [childElement.textContent stringByTrimmingCharactersInSet:whitespace];
                            // 컨텐츠 내용들 받아주기.
                            if (![@"" isEqualToString:content]) {
                                vm.caption = [NSString stringWithFormat:@"%@\n%@",vm.caption,content];
                            }
                        }
                    }
                }
            }
        }

        complete(vm);

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        fail(error);
    }];
}
@end
<file_sep>/iOS_Kimjiwook/iOS_Kimjiwook/VM/ViewModel.m
//
//  ViewModel.m
//  iOS_Kimjiwook
//
//  Created by kimjiwook on 2018. 4. 11..
//  Copyright © 2018년 kimjiwook. All rights reserved.
//

#import "ViewModel.h"

/// 1. 메인.
@implementation ViewModel
- (id)init {
    self = [super init];
    if (self) {
        _detailURL = @"";
        _thumImageURL = @"";
        _caption = @"";
        _thumImage = nil;
    }
    return self;
}

@end

/// 2. 상세
@implementation DetailViewModel
- (id)init {
    self = [super init];
    if (self) {
        _imageURL = @"";
        _caption = @"";
        _detailImage = nil;
    }
    return self;
}
@end
<file_sep>/iOS_Kimjiwook/iOS_Kimjiwook/ViewController/MainTableViewCell.h
//
//  MainTableViewCell.h
//  iOS_Kimjiwook
//
//  Created by JW_Macbook on 2018. 4. 11..
//  Copyright © 2018년 kimjiwook. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "ViewModel.h"

@interface MainTableViewCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UIImageView *imgView;
@property (weak, nonatomic) IBOutlet UILabel *lbTitle;

/// 1. Cell 내용 셋팅하는 부분.
- (void)configuration:(ViewModel *)vm indexPath:(NSIndexPath *)indexPath;
@end
<file_sep>/iOS_Kimjiwook/iOS_Kimjiwook/ViewController/RootViewController.h
//
//  RootViewController.h
//  iOS_Kimjiwook
//
//  Created by kimjiwook on 2018. 4. 12..
//  Copyright © 2018년 kimjiwook. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "ProtocolList.h"

@interface RootViewController : UIViewController
@property (strong, nonatomic) LOTAnimationView *lotAnimationView;
@property (strong, nonatomic) ProtocolList *protocolList;

/// 로딩뷰 시작 / 종료
- (void)startLodingView;
- (void)stopLodingView;
/// AutoLayout 잡을 용도.
- (void)addConstraintZero:(UIView *)view toView:(UIView *)toView;
@end
<file_sep>/iOS_Kimjiwook/iOS_Kimjiwook/ViewController/RootViewController.m
//
//  RootViewController.m
//  iOS_Kimjiwook
//
//  Created by kimjiwook on 2018. 4. 12..
//  Copyright © 2018년 kimjiwook. All rights reserved.
//

#import "RootViewController.h"

@interface RootViewController ()

@end

@implementation RootViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/**
 로딩뷰 시작.
 */
- (void)startLodingView {
    if (!self.lotAnimationView) {
        self.lotAnimationView = [LOTAnimationView animationNamed:@"loding3"];
        self.lotAnimationView.contentMode = UIViewContentModeScaleAspectFit;
        self.lotAnimationView.loopAnimation = YES;
    }
    [self.view addSubview:self.lotAnimationView];
    [self addConstraintZero:self.lotAnimationView toView:self.view];
    [self.lotAnimationView play];
}

/**
 로딩뷰 종료.
 */
- (void)stopLodingView {
    [self.lotAnimationView stop];
    [self.lotAnimationView removeFromSuperview];
}

/**
 *  AutoLayout 위,아래,왼쪽,오른쪽이 (0)인 경우!!!
 *
 *  @param view   적용할 View
 *  @param toView 부모 View
 */
- (void)addConstraintZero:(UIView *)view toView:(UIView *)toView {
    [self addConstraint:view toView:toView topConstraint:@(0) topIdentifier:nil bottomConstraint:@(0) bottomIdentifier:nil leadingConstraint:@(0) leadingIdentifier:nil trailingConstraint:@(0) trailingIdentifier:nil widthConstraint:nil widthIdentifier:nil heightConstraint:nil heightIdentifier:nil centerXConstraint:nil centerXIdentifier:nil centerYConstraint:nil centerYIdentifier:nil];
}

//Autolayout 설정
- (void)addConstraint:(UIView *)view toView:(UIView *)toView
        topConstraint:(NSNumber *)topConstraint topIdentifier:(NSString *)topIdentifier
     bottomConstraint:(NSNumber *)bottomConstraint bottomIdentifier:(NSString *)bottomIdentifier
    leadingConstraint:(NSNumber *)leadingConstraint leadingIdentifier:(NSString *)leadingIdentifier
   trailingConstraint:(NSNumber *)trailingConstraint trailingIdentifier:(NSString *)trailingIdentifier
      widthConstraint:(NSNumber *)widthConstraint widthIdentifier:(NSString *)widthIdentifier
     heightConstraint:(NSNumber *)heightConstraint heightIdentifier:(NSString *)heightIdentifier
    centerXConstraint:(NSNumber *)centerXConstraint centerXIdentifier:(NSString *)centerXIdentifier
    centerYConstraint:(NSNumber *)centerYConstraint centerYIdentifier:(NSString *)centerYIdentifier
{
    view.translatesAutoresizingMaskIntoConstraints = NO;

    if (topConstraint) {
        if(toView && toView) {
            NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:view
                                                                          attribute:NSLayoutAttributeTop
                                                                          relatedBy:NSLayoutRelationEqual
                                                                             toItem:toView
                                                                          attribute:NSLayoutAttributeTop
                                                                         multiplier:1.0f
                                                                           constant:[topConstraint floatValue]];
            if (topIdentifier && ![@"" isEqualToString:topIdentifier]) {
                constraint.identifier = topIdentifier;
            }

            [toView addConstraint:constraint];
        }
    }

    if (bottomConstraint) {
        NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:view
                                                                      attribute:NSLayoutAttributeBottom
                                                                      relatedBy:NSLayoutRelationEqual
                                                                         toItem:toView
                                                                      attribute:NSLayoutAttributeBottom
                                                                     multiplier:1.0f
                                                                       constant:[bottomConstraint floatValue]];
        if (bottomIdentifier && ![@"" isEqualToString:bottomIdentifier]) {
            constraint.identifier = bottomIdentifier;
        }

        [toView addConstraint:constraint];
    }

    if (leadingConstraint) {
        NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:view
                                                                      attribute:NSLayoutAttributeLeading
                                                                      relatedBy:NSLayoutRelationEqual
                                                                         toItem:toView
                                                                      attribute:NSLayoutAttributeLeading
                                                                     multiplier:1.0f
                                                                       constant:[leadingConstraint floatValue]];
        if (leadingIdentifier && ![@"" isEqualToString:leadingIdentifier]) {
            constraint.identifier = leadingIdentifier;
        }

        [toView addConstraint:constraint];
    }

    if (trailingConstraint) {
        NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:view
                                                                      attribute:NSLayoutAttributeTrailing
                                                                      relatedBy:NSLayoutRelationEqual
                                                                         toItem:toView
                                                                      attribute:NSLayoutAttributeTrailing
                                                                     multiplier:1.0f
                                                                       constant:[trailingConstraint floatValue]];
        if (trailingIdentifier && ![@"" isEqualToString:trailingIdentifier]) {
            constraint.identifier = trailingIdentifier;
        }

        [toView addConstraint:constraint];
    }

    if (widthConstraint) {
        NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:view
                                                                      attribute:NSLayoutAttributeWidth
                                                                      relatedBy:NSLayoutRelationEqual
                                                                         toItem:nil
                                                                      attribute:NSLayoutAttributeNotAnAttribute
                                                                     multiplier:1.0f
                                                                       constant:[widthConstraint floatValue]];
        if (widthIdentifier && ![@"" isEqualToString:widthIdentifier]) {
            constraint.identifier = widthIdentifier;
        }

        [view addConstraint:constraint];
    }

    if (heightConstraint) {
        NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:view
                                                                      attribute:NSLayoutAttributeHeight
                                                                      relatedBy:NSLayoutRelationEqual
                                                                         toItem:nil
                                                                      attribute:NSLayoutAttributeNotAnAttribute
                                                                     multiplier:1.0f
                                                                       constant:[heightConstraint floatValue]];
        if (heightIdentifier && ![@"" isEqualToString:heightIdentifier]) {
            constraint.identifier = heightIdentifier;
        }

        [view addConstraint:constraint];
    }

    if (centerXConstraint) {
        NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:view
                                                                      attribute:NSLayoutAttributeCenterX
                                                                      relatedBy:NSLayoutRelationEqual
                                                                         toItem:toView
                                                                      attribute:NSLayoutAttributeCenterX
                                                                     multiplier:1.0f
                                                                       constant:[centerXConstraint floatValue]];
        if (centerXIdentifier && ![@"" isEqualToString:centerXIdentifier]) {
            constraint.identifier = centerXIdentifier;
        }

        [toView addConstraint:constraint];
    }

    if (centerYConstraint) {
        NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:view
                                                                      attribute:NSLayoutAttributeCenterY
                                                                      relatedBy:NSLayoutRelationEqual
                                                                         toItem:toView
                                                                      attribute:NSLayoutAttributeCenterY
                                                                     multiplier:1.0f
                                                                       constant:[centerYConstraint floatValue]];
        if (centerYIdentifier && ![@"" isEqualToString:centerYIdentifier]) {
            constraint.identifier = centerYIdentifier;
        }

        [toView addConstraint:constraint];
    }

}

@end
<file_sep>/iOS_Kimjiwook/iOS_Kimjiwook/Util/NSObject+Associating.h
//
//  NSObject+Associating.h
//  iOS_Kimjiwook
//
//  Created by kimjiwook on 2018. 4. 12..
//  Copyright © 2018년 kimjiwook. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

@interface NSObject (Associating)
/// 셀 이미지 작업시 이미지를 덮어쓰는 경우가 발생을 방지하기 위해 작업을 대기함.
@property (nonatomic, retain) id associatedObject;
@end
<file_sep>/iOS_Kimjiwook/iOS_Kimjiwook/VM/ViewModel.h
//
//  ViewModel.h
//  iOS_Kimjiwook
//
//  Created by kimjiwook on 2018. 4. 11..
//  Copyright © 2018년 kimjiwook. All rights reserved.
//

#import <Foundation/Foundation.h>

/// 1. 메인 리스트. VM
@interface ViewModel : NSObject
@property (nonatomic, strong) NSString *detailURL; // 1. 상세정보 URL (호출후 Parser 진행해야함.)
@property (nonatomic, strong) NSString *thumImageURL; // 2. 썸네일 이미지 URL
@property (nonatomic, strong) NSString *caption; // 3. 해당 이미지의 설명글

@property (nonatomic, strong) UIImage *thumImage; // 2-1. 이미지 부분.
@end

/// 2. 상세화면. VM
@interface DetailViewModel : NSObject
@property (nonatomic, strong) NSString *imageURL; // 1. 상세 이미지 URL
@property (nonatomic, strong) NSString *caption; // 2. 설명글

@property (nonatomic, strong) UIImage *detailImage; // 1-1. 이미지 영역.
@end
<file_sep>/iOS_Kimjiwook/iOS_Kimjiwook/Util/NSObject+Associating.m
//
//  NSObject+Associating.m
//  iOS_Kimjiwook
//
//  Created by kimjiwook on 2018. 4. 12..
//  Copyright © 2018년 kimjiwook. All rights reserved.
//

#import "NSObject+Associating.h"

@implementation NSObject (Associating)

- (id)associatedObject
{
    return objc_getAssociatedObject(self, @selector(associatedObject));
}

- (void)setAssociatedObject:(id)associatedObject
{
    objc_setAssociatedObject(self,
                             @selector(associatedObject),
                             associatedObject,
                             OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

@end
<file_sep>/iOS_Kimjiwook/iOS_Kimjiwook/ViewController/MainViewController.m
//
//  MainViewController.m
//  iOS_Kimjiwook
//
//  Created by kimjiwook on 2018. 4. 11..
//  Copyright © 2018년 kimjiwook. All rights reserved.
//

#import "MainViewController.h"
#import "ViewModel.h"

#import "DetailViewController.h"
#import "MainTableViewCell.h"

@interface MainViewController () {
    NSMutableArray *dataList;
}

/// 메인으로 사용되는 테이블 뷰.
@property (weak, nonatomic) IBOutlet UITableView *tableView;

@end

@implementation MainViewController

#pragma mark - #. 기본적인 사항들.

/**
 초기화와 기본적인 셋팅을 맞는 부분.
 */
- (void)initData {
    dataList = [[NSMutableArray alloc] init];
    self.protocolList = [[ProtocolList alloc] init];
    [self setNavigation];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"시작점.");
    [self initData];
    [self requestHTML];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/**
 네비게이션 정보.
 */
- (void)setNavigation {
    self.title = @"iOS_김지욱";

    [self.navigationController.navigationBar setBarTintColor:[UIColor colorWithRed:0.31 green:0.25 blue:0.21 alpha:1.0f]];
    [self.navigationController.navigationBar setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys:
                                                                      [UIColor whiteColor], NSForegroundColorAttributeName
                                                                      , nil]];
    [self.navigationController.navigationBar setTintColor:[UIColor whiteColor]];
}

/**
 HTML ParserData 호출 후 뿌려주는 부분.
 */
- (void)requestHTML {
    [self startLodingView];
    [self.protocolList getImageArray:^(id ob) {
        self->dataList = [(NSMutableArray *)ob mutableCopy];
        self.tableView.hidden = NO;
        [self.tableView reloadData];
        [self stopLodingView];
    } :^(NSError *error) {
        NSLog(@"error : %@",error);
        [self stopLodingView];
    }];
}

#pragma mark- UITableView Delegate,DataSource
// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return dataList.count;
}

#pragma mark ㄴ TableView Cell 높이 관련.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return UITableViewAutomaticDimension;
}

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return UITableViewAutomaticDimension;
}

#pragma mark ㄴ TableView 꾸미는 관련.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *cellIdentifier = @"MainTableViewCell";

    MainTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (!cell) {
        [tableView registerNib:[UINib nibWithNibName:@"MainTableViewCell" bundle:nil] forCellReuseIdentifier:cellIdentifier];
        cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    }

    // 데이터.
    ViewModel *vm = [dataList objectAtIndex:indexPath.row];
    // Cell 꾸며주는 부분.
    [cell configuration:vm indexPath:indexPath];

    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
    // 데이터.
    ViewModel *vm = [dataList objectAtIndex:indexPath.row];

    // 상세화면 이동
    DetailViewController *desc = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
    desc.navigationTitle = vm.caption;
    desc.detailUrl = vm.detailURL;
    [self.navigationController pushViewController:desc animated:YES];
}
@end

repo_language: Objective-C


text:
<file_sep>//
//  VPVideoStreamPlayLayer.h
//  HSZAVPlay
//
//  Created by <NAME> on 2020/10/21.
//

#import <QuartzCore/QuartzCore.h>
#import <CoreVideo/CoreVideo.h>

NS_ASSUME_NONNULL_BEGIN

@interface VPVideoStreamPlayLayer : CAEAGLLayer

/** 根据frame初始化播放器 */
- (id)initWithFrame:(CGRect)frame;

- (void)inputPixelBuffer:(CVPixelBufferRef)pixelBuffer;

@end

NS_ASSUME_NONNULL_END
<file_sep>//
//  H264Decoder.h
//  HSZAVPlay
//
//  Created by <NAME> on 2020/10/21.
//

#import <Foundation/Foundation.h>
#import <VideoToolbox/VideoToolbox.h>

@protocol H264DecoderDelegate <NSObject>

/** H264解码数据回调 */
- (void)videoDecodeOutputDataCallback:(CVImageBufferRef)imageBuffer;

@end

NS_ASSUME_NONNULL_BEGIN

@interface H264Decoder : NSObject

/** 代理 */
@property (weak, nonatomic) id<H264DecoderDelegate> delegate;

/** 解码NALU数据 */
-(void)decodeNaluData:(NSData *)naluData;

@end

NS_ASSUME_NONNULL_END
<file_sep>//
//  MetalPlayer.h
//  HSZAVPlay
//
//  Created by <NAME> on 2020/10/21.
//

#import <QuartzCore/QuartzCore.h>
#import <CoreVideo/CoreVideo.h>

NS_ASSUME_NONNULL_BEGIN

@interface MetalPlayer : CAMetalLayer

- (void)adjustSize:(CGSize)size;

- (void)inputPixelBuffer:(CVPixelBufferRef)pixelBuffer;

- (instancetype)initWithFrame:(CGRect)frame;

@end

NS_ASSUME_NONNULL_END

repo_name: HeShaoZe/HSZAVPlay


text:
<repo_name>Dsyko/meteor-moment<file_sep>/README.md
# Moment for Meteor

[Moment.js](http://momentjs.com/), a JavaScript date library for parsing, validating, manipulating, and formatting dates, packaged for Meteor.

Please note, this version is [hosted](https://atmosphere.meteor.com/package/moment-alternative) on [atmosphere](https://atmosphere.meteor.com/) as "moment-alternative" simply because the orignal "moment" meteorite package has not been updated for some time.

Installation
-------------

`mrt add moment-alternative`

Usage
-------------
Just like the [moment docs](http://momentjs.com/docs/) tell you:

`var oneMonentPlease = moment()`

repo_name: Dsyko/meteor-moment


text:
<file_sep>#!/usr/bin/env python
# coding: utf-8

# In[1]:

import pandas as pd
import sqlite3
import numpy as np

# # 1. Import, Restructure, and Clean Data

# In[2]:

#define connection
conn = sqlite3.connect('database.sqlite')

# In[3]:

#write query for first import (weather)
query = """SELECT date, mean_temperature_f, precipitation_inches, mean_wind_speed_mph FROM weather"""

# In[4]:

#read in the weather table. set index as date to prevent multiindex default
weather = pd.read_sql_query(query, conn, parse_dates = ['date'], index_col = 'date')
weather.reset_index(inplace = True)
weather.replace("", np.nan)

# In[5]:

#drop NAs from the weather table
weather.dropna(inplace = True)

# In[6]:

#sort weather df by date, and drop the duplicates, keeping the first instance of each
weather.sort_values(by = 'date', inplace = True)
weather = weather[weather.mean_temperature_f != '']
weather_drop = weather.drop_duplicates(subset = 'date', keep = 'first').reset_index().drop('index', axis=1)

# In[7]:

# replace all instance of T (trace) in the precip column with 0.005
weather_drop['precipitation_inches'].replace('T', 0.005, inplace = True)

# In[8]:

#convert precip and temp/wind cols to flt and int dtypes respectively
weather_drop['precipitation_inches'].astype('float')
weather_drop[['mean_temperature_f', 'mean_wind_speed_mph']] = weather_drop[['mean_temperature_f', 'mean_wind_speed_mph']].astype('int')

# In[9]:

#extract year and day number from date col, and drop date col
weather_drop['dayofyear'] = weather_drop['date'].dt.dayofyear.astype(int)
weather_drop['year'] = weather_drop['date'].dt.year.astype(int)
weather_drop.drop('date', axis = 1, inplace = True)
weather_drop.info()

# In[10]:

#read in station table from sql db
query = """SELECT id, lat, long, dock_count
            FROM station"""

stations = pd.read_sql_query(query, conn)
stations['dock_count'] = stations['dock_count'].astype(int)
stations.columns = ['station_id', 'lat', 'long', 'dock_count']
stations['station_id'] = stations['station_id'].astype(int)
stations.info()

# In[11]:

#read in status table in chunks of 10**6
status_chunk = pd.read_csv('status.csv',
                           usecols = ['station_id', 'bikes_available', 'time'],
                           parse_dates = ['time'],
                           chunksize = 10**6,
                          iterator = True)

#create an empty df with the appropriate col names
status = pd.DataFrame(columns=['station_id', 'bikes_available', 'time'])

#use for loop to take samples of the chunks and append them to the the status df
for chunk in status_chunk:
    chunk = chunk.sample(frac = 0.1)
    status = status.append(chunk)

# In[12]:

#convert station_id and bikes_available columns to int type
status[['station_id', 'bikes_available']] = status[['station_id', 'bikes_available']].astype(int)

# In[13]:

status.info()

# In[14]:

#break down the datetime into its individual features and drop the original datetime
status['dayofweek'] = status['time'].dt.dayofweek
status['min_in_day'] = status['time'].dt.hour * 60 + status['time'].dt.minute
status['dayofyear'] = status['time'].dt.dayofyear
status['year'] = status['time'].dt.year

status.drop('time', axis = 1, inplace = True)

status = status.astype(int)

status.info()

# In[15]:

#merge status and weather dfs on 'dayofyear' and 'year'.
status = status.merge(weather_drop, how = 'left', on = ['dayofyear', 'year'])

#merge status and stations dfs on station_id
status = status.merge(stations, how = 'left', on = 'station_id')

# In[16]:

#write the full merged dataframe to a csv
#status.to_csv('status_stn_wx_full.csv')

# In[17]:

status.info()

# In[ ]:

# # 3. Exploratory Data Analysis

# In[18]:

import matplotlib.pyplot as plt

# In[19]:

#take a randome sample of 1e6 data to get an idea of trends that are present
#status_sample = status.sample(10**6)
#status_sample.info()

# In[20]:

#plot differences in bike availability by day of the week
plt.plot(status.groupby("dayofweek").bikes_available.mean())

# In[21]:

#plot the histogram of bike availabilities at all stations
plt.hist(status["bikes_available"], bins = (status["bikes_available"].max() + 1))
plt.axvline(status["bikes_available"].median(), color = 'red')
plt.axvline(status["bikes_available"].median() + status["bikes_available"].std(), color = 'yellow')
plt.axvline(status["bikes_available"].median() - status["bikes_available"].std(), color = 'yellow')

# In[22]:

#plot how biek avavilability changes over the course of the day
plt.plot(status.groupby(["min_in_day"])["bikes_available"].mean())

# In[23]:

##plot differences in bike availability by day of the year
plt.plot(status.groupby("dayofyear").bikes_available.mean())

# # 4. Data Preprocessing

# In[24]:

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# In[25]:

#take a sample of size sample_size from status_merge to do test runs on ML model
#using the same var name so that this cell can be easily removed for a full run
sample_size = 1250000
status = status.sample(n = sample_size, random_state = 42)

# In[26]:

#instantiate standard scaler
scaler = StandardScaler()

# In[27]:

#scale min_in_day, lat, long, and dock_count cols
status[['mean_temperature_f','precipitation_inches', 'mean_wind_speed_mph', 'lat', 'long', 'dock_count', 'min_in_day', 'dayofyear']] = scaler.fit_transform(status[['mean_temperature_f','precipitation_inches', 'mean_wind_speed_mph', 'lat', 'long', 'dock_count', 'min_in_day', 'dayofyear']])

# In[28]:

#convert station_id and year to categeoricals, then one-hot encode them
status[['station_id', 'year', 'dayofweek']] = status[['station_id', 'year', 'dayofweek']] .astype('category')
status = pd.get_dummies(status)

# In[29]:

#create X and y
bikes = status['bikes_available']
status = status.drop('bikes_available', axis = 1)

# In[30]:

bikes = bikes.values
status = status.values

# In[31]:

#find the shape of X_scale to use as the input dimension, asigning the length and width to l and w
l, w = status.shape

# In[32]:

#create a train/test split of the data set being used in the model
X_train, X_test, y_train, y_test = train_test_split(status, bikes, test_size = 0.2, random_state = 21)

# # 5. Create Neural Net ML Model

# In[ ]:

#import necessary elements of ML model
from keras.models import Sequential
from keras.layers import Dense, BatchNormalization
from keras.callbacks import EarlyStopping
from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.model_selection import train_test_split, cross_val_score, RandomizedSearchCV

# In[34]:

#define a function that creates a keras model with parameters optimizer,
#activation, nl (number of layers), and nn (number of neurons)
def create_model(opt = 'adam', act = 'relu', nl = 1, nn = 32):
    model = Sequential()
    model.add(Dense(nn, input_shape = (w,), activation = act))
    for i in range(nl):
        model.add(Dense(nn, activation = act))
    model.add(Dense(1, activation = act))
    model.compile(optimizer = opt, loss = 'mse', metrics = ['mse', 'mean_absolute_error'])
    return model

#create model as an sklearn regressor
model = KerasRegressor(build_fn = create_model, epochs = 5)

#set params to search over
params = dict(opt = ['adam'],
              act = ['relu'],
              nl = [1, 2, 3, 4],
              nn = [32, 64, 128])

# In[35]:

#create random search cv object
random_search = RandomizedSearchCV(model, param_distributions = params, cv = 5, n_iter = 10)

random_search_results = random_search.fit(status, bikes)

# In[36]:

#print the best score obtained from the RandomizedSearchCV
random_search_results.best_score_

# In[77]:

#assign the best set of parameters to final_params
final_params = random_search_results.best_params_
print(final_params)

# In[38]:

#establish the optimized model using the parameters from final_params
create_model(final_params['opt'], final_params['act'], final_params['nl'], final_params['nn'])

#set up an early stopping callback with a patience of 3
early_stopping = EarlyStopping(monitor = 'val_loss', patience = 3)

#run the model with 25 epochs, saving the results to history
history = model.fit(X_train, y_train,
                    epochs = 25,
                    validation_split = 0.2,
                    callbacks = [early_stopping])

# # 6. Evaluate Model

# In[39]:

#plot the training and validation loss over each epoch
plt.plot(history.history['mse'])
plt.plot(history.history['val_mse'])
plt.title('Model Accuracy by Epoch')
plt.xlabel('Epoch')
plt.ylabel('Mean Squared Error')
plt.legend({'Train', 'Validation'})

plt.savefig('model_acc_latlong.png', dpi=300)

# In[44]:

y_pred = model.predict(X_test)

# In[75]:

#bind y_test and pred into a single df/ndarray and take a random sample to plot
bound_vals = pd.DataFrame(columns= ['predicted', 'actual'])
bound_vals['predicted'] = y_pred
bound_vals['actual'] = y_test

bound_vals_sample = bound_vals.sample(5000)

# In[76]:

#plot the test vals against the predictions
plt.scatter(bound_vals_sample['actual'], bound_vals_sample['predicted'], color = 'darkred', alpha = 0.05)
plt.title('Predicted Values vs. Actual Values')
plt.xlabel('Actual Value')
plt.ylabel('Predicted Value')

plt.savefig('pred_act_scatter_new.png', dpi=300)

# In[ ]:

<file_sep># Bike Availability in the SFMTA Bikeshare System
## Neural Network Machine Learning for Regression

#### Motivation
One of the benefits of the advancement of dockless bikeshare programs is that no individual station can be void of bikes to check out, or full of bikes, preventing a check in. However, dock-based bikeshare systems are still commonplace throughout the country, and due to the large capital investment they required, will likely remain so for some time. San Francisco MTA runs one of the largest dock-based bikeshare systems in the country, and has made data about its usage [publicaly available](https://www.sfmta.com/getting-around/bike/bike-share#Bikeshare%20Data).

Joining the bike usage data with weather data from [Kaggle](https://www.kaggle.com/benhamner/sf-bay-area-bike-share), I was able to generate a useful set of inputs that could help determine the likely number of bikes available at a given dock, based on the weather, location, day, and time.

#### Methods
The dataset used for this project was very large, and scaled up rapidly as additional variables were created.

I managed the import of data by using SQLite, and randomly sampling the import to speed up computation. The status file in particular was quite large, so that import was handled in chunks, and the chunks were sampled individually.

Disparate data sets were merged in Python, using the Pandas package. The weather dataset was pretty messy, so missing and duplicate data had to be dealt with using a combination of methods.

Time series data was handled by breaking the datetimes into constituent parts and analyzing those parts as discrete values.

The exploratory data analysis showed that the primary input values had individual predictive power, suggesting that they would be even better in concert. I constructed a sequential model in Keras, and used RandomizedSearchCV to tune the hyperparameters to their optimal values.

#### Outcomes
The final model had a mean absolute error of 2.2, which was much lower than the standard deviation of 4.0. This suggested a strongly predictive model that produced statistically robust predictions.

This system could be used as a stand-alone, or it could possibly be integrated into a trip planning system to help direct users to docks where bikes are more likely to be available at the time of the planned trip.