본문 바로가기

[Recoeve.net]

Career Portfolio - Kang-soo Lee

반응형
# Career Portfolio - Kang-soo Lee Physicist, Programmer. My favorite motto is "What you eat, how you think, and most importantly what you have done become who you are. Who are you? and who will you be?"
My pictures
## PH
  • 2025-02-14 : Codeit Fullstack 2nd added. Recoeve.net added. MBTI removed.
  • 2023-05-31 : MBTI added.
  • 2017-03-21 : Update and Clean up.
  • 2016-03-16 : Update and Clean up.
  • 2015-12-23 : Update.
  • 2015-12-18 : First posting.
## TOC ##[.no-sec-N#sec-CV] Curriculum vitae
  • 2002-03 ~ 2006-02: Diploma studies in Physics at KAIST, Korea.
    // Simple Research on Quantum Dot and Quantum Information theory.
    // Graduation thesis on ‘Electro-Magnetism with General Relativity’; Crude try on explanation of electro-magnetic forces from gravity only. See .
  • 2007-09 ~ 2013-12: Entered Seoul National University.
    // Combined master’s and doctorate course in Experimental Lab and Theoritical Lab .
    // But dropped at 2013 since I don't care about insignificant certificate of Doctorial degree.
    // Published papers are listed in Subsec. .
  • 2011-04 ~ 2011-05: Gorvernment Millitary Service, 4 weeks traning.
  • 2014 ~ Now: Developed recoeve.net .
  • 2017-07 ~ 2017-10: Skelter Labs intern (3 months).
    // The proudest program which I coded alone is the one to correct inaccurate location measured by GPS with wifi RSSI (Received Signal Strength Indicatior) .
  • 2018-04-21 ~ 2024-08-05: Managed Emart24 learning economies .
  • 2024-07-25 ~ 2025-02-26: Government-assisted bootcamp Codeit FullStack 2nd batch (Learned HTML, CSS, JavaScript, TypeScript, React, Next.js, tanstack/react-query, tailwindCSS, Docker, CI/CD (Github Action))
SNU
### Some other remarks
  • Feb. 2008 ~ Spring 2010: Programmed plenty of Labview, C++ programs. Almost of them analyze image files taken from microscope with vector calculus. Some of them compile statistics on properties of magnetic domain.
  • Jan. 2010: Organized ‘3rd BK21 Young Physicists Workshop’. A committee of arrangements.
###[#subsec-papers] Papers Published (and Selected ones which I am proud of.) #### Truncated many-body dynamics of interacting bosons: A variational principle with error monitoring Read More : http://www.worldscientific.com/doi/abs/10.1142/S0217979215500216 This is one of my favorite papers published, although many would not understand this well enough. See it in docuK html form in .
Cited 17 times until 2025-03-01. #### Emergence of a new pair-coherent phase in many-body quenches of repulsive bosons
#### Universality Classes of Magnetic Domain Wall Motion
#### Long-Range Domain Wall Tension in Pt/Co/Pt Films with Perpendicular Magnetic Anisotropy
## Recoeve.net (Ongoing solo project) A service currently under development. Key points include Fuzzy search and Multi-Categorized Records. Developed using Vert.x JAVA server + MySQL JDBC (Java DataBase Connector) + Javascript, jQuery, AJAX, React, etc. Single Page Application (SPA) with using history.pushState. The key is user-collaborative recommendation using machine learning . Self-customizing + Multi-Categorized Records, or Scrapbook, for Everything, and Personalized Recommendation for Everything at each Category, which can be called Computer-Assisted Cloud/Crowd Curating. The below page is [Music/Break]--K-Pop of kipid's Recoeve.net.
Development Notes: Recoeve progress ### Fuzzy search I applied Fuzzy search to almost everything to make it easy to find things you've recoed, to make it easy to select categories, and to move between categories.
### Structured and Multi Categorization Similar to the Tag function, but structured categorization with a hierarchical structure is possible. Like Tag, multiple categories can be specified in one reco using the delimiter ";". Fuzzy search is also implemented so that it can be used when entering a category. Category jump is also possible through the link in the category section of Reco.
### Change orders of category list I designed and implemented it so that users can easily change the location of the category list. You can test it on my page https://recoeve.net/user/kipid. (I designed it so that you can change the location of the category list even if it is not your page. Since it is not your page, this order will be maintained only until you refresh the page. If you refresh, it will return to the original user's category list order.)
### Multilingual support through Pattern replace Designed to support multilingual easily through Pattern replace.
Find [--Pattern--] pattern and replace in multiple languages. Below is a part of the code. ```[.linenums.scrollable.lang-java] public static final Pattern ptnReplacer=Pattern.compile("\\[--[\\s\\S]+?--\\]"); public static final Pattern ptnVariable=Pattern.compile("\\{--[\\s\\S]+?--\\}"); static { fileMap=new HashMap<String, Map<String, ArrayList<String>>>(fileMapSize); File file=null; String fileStr=null; file=new File(filePath+"lang.txt"); if (file.exists()) { try { StringBuilder sb=new StringBuilder(); int ch; FileReader reader=new FileReader(file); while((ch=reader.read())!=-1) { sb.append((char)ch); } reader.close(); fileStr=sb.toString(); } catch (IOException e) { System.out.println(e); } finally { file=null; } } StrArray langMap=new StrArray(fileStr, true, true); // System.out.println(langMap); fileStr=null; for (String fileName: fileNames) { file=new File(filePath+fileName); if (file.exists()) { try { StringBuilder sb=new StringBuilder(); int ch; FileReader reader=new FileReader(file); while((ch=reader.read())!=-1) { sb.append((char)ch); } reader.close(); fileStr=sb.toString(); } catch (IOException e) { System.out.println(e); } finally { file=null; } } if (fileStr!=null) { // System.out.println("\nfileName : "+fileName); fileMap.put(fileName, new HashMap<String, ArrayList<String>>(fileLangMapSize)); Map<String, ArrayList<String>> fileLangMap=fileMap.get(fileName); ArrayList<String> strListVars=new ArrayList<String>(); Matcher matchVariable=ptnVariable.matcher(fileStr); // default int start=0; while (start<fileStr.length()) { if (matchVariable.find(start)) { strListVars.add(fileStr.substring(start, matchVariable.start())); strListVars.add(matchVariable.group()); start=matchVariable.end(); } else { strListVars.add(fileStr.substring(start)); start=fileStr.length(); } } fileLangMap.put("df", strListVars); // default. ArrayList<String> strList=new ArrayList<String>(); Matcher matchReplacer=ptnReplacer.matcher(fileStr); start=0; while (start<fileStr.length()) { if (matchReplacer.find(start)) { strList.add(fileStr.substring(start, matchReplacer.start())); strList.add(matchReplacer.group()); start=matchReplacer.end(); } else { strList.add(fileStr.substring(start)); start=fileStr.length(); } } if (strList.size()>1) { int colSize=langMap.getColSizeAtRow(0); for (int k=2;k<colSize;k++) { String lang=langMap.get(0,k); if (!lang.equals("desc")) { String strReplaced=""; String replaced=null; for (int i=0;i<strList.size();i++) { if (i%2==0) { strReplaced+=strList.get(i); } else { replaced=langMap.get(strList.get(i), lang); if (replaced==null||replaced.isEmpty()||replaced.equals("-")) { replaced=langMap.get(strList.get(i), "en"); // "en" is default lang. } if (replaced==null) { replaced=strList.get(i); } strReplaced+=replaced; } } strListVars=new ArrayList<String>(); matchVariable=ptnVariable.matcher(strReplaced); // [--lang--] replaced start=0; while (start<strReplaced.length()) { if (matchVariable.find(start)) { strListVars.add(strReplaced.substring(start, matchVariable.start())); strListVars.add(matchVariable.group()); start=matchVariable.end(); } else { strListVars.add(strReplaced.substring(start)); start=strReplaced.length(); } } fileLangMap.put(lang, strListVars); // after replacing langMap. } } } fileStr=null; } } } public FileMapWithVar() {} public static String get(String fileName, String lang, Map<String,String> varMap) { Map<String, ArrayList<String>> fileLangMap=fileMap.get(fileName); if (fileLangMap==null) {return null;} ArrayList<String> strList=fileLangMap.get(lang); if (strList==null) { strList=fileLangMap.get("df"); } String res=""; String replaced=null; for (int i=0;i<strList.size();i++) { if (i%2==0) { res+=strList.get(i); } else { replaced=varMap.get(strList.get(i)); if (replaced==null) { replaced=strList.get(i); } res+=replaced; } } return res; } ```/ ### Recoeve.net as a player of the list of YouTubes and videos I used the YouTube API to enable continuous playback of YouTube videos that I recoed. I designed it so that I could play just one video repeatedly or the entire video repeatedly, and I also implemented a Shuffle function. If a recoed YouTube video cannot be played, I also implemented error handling so that the next video will be played 10 seconds later. You can try the test at https://recoeve.net/user/kipid?cat=[Music/Break]--K-Pop. ### Reco example :: Reco Youtube Video
### Recoeve widget (Export to Recoeve) I made a Recoeve widget to enable SNS export like X or facebook .
### Watch video and lyrics together When you enter lyrics through #lyrics in the Reco description, you can design the lyrics to be folded and unfolded with the Toggle lyrics button. The video can be attached to the top left with the stick to the left top button.
### Scalable design We designed it to be Responsible/Scalable through CSS media queries so that it works well on smartphones as well.
```[.linenums.scalable.lang-css] @media all and (min-width:701px) { #container {margin-left:14.9em} #sidebar {margin:0; position:fixed; left:0; top:0; bottom:0; width:15em} #sidebar-dragger {display:none} #sidebar-exit {display:none} .side2 {padding:.5em} .rC.fixed {width:646px; border-right:.15em solid black} .lyrics {text-align:right} ::-webkit-scrollbar {width:11px; height:11px} } @media all and (min-width:901px) { #container {margin-left:19.9em} #sidebar {width:20em} } @media all and (min-height:500px) { #fuzzy-search-list {max-height:430px;} } ```/ ### Login password hacking prevention system Using one-way encryption (Hash) with iteration, it is designed to be somewhat immune to hacking that intercepts the network in the middle. The user side javascript side sends 10000 iterations at first. Then, it sends 9999 iterations and the rest are checked through iterations on the server. It is designed so that hacking is impossible even with encrypted passwords intercepted in the middle of the network, as long as the user password is not hacked. However, the iteration on the user side should always decrease. Otherwise, the hash function is exposed to javascript, so the iterations in the back can be inferred. The server's user data should store iteration information, and when the user logs in, send only the ID/e-mail first with AJAX to receive the number of password iterations, and then encrypt it with iterations and send the entire data. ```[.linenums.scrollable.lang-javascript] eve.encrypt=function(salt, pwd, iter) { iter=pwd.length+131+((iter&&iter.constructor==Number&&iter>=0)?iter:0);; pwd=salt+pwd; var h1=eve.hash1(pwd); var h2=eve.hash2(pwd); var h3=eve.hash3(pwd); var h4=eve.hash4(pwd); var h5=eve.hash5(pwd); var h6=eve.hash6(pwd); var h7=eve.hash7(pwd); var h8=eve.hash8(pwd); var h9=eve.hash9(pwd); var h10=eve.hash10(pwd); var h11=eve.hash11(pwd); var h12=eve.hash12(pwd); var h13=eve.hash13(pwd); var tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13; for (var i=0;i<iter;i++) { tmp1=h13+h12+h11+h10+h9+salt+h8+h7+h6+h5+h4+h3+h2+h1; tmp2=h1+h3+salt+h2; tmp3=salt+h2+h8+h1+h3; tmp4=h7+salt+h5; tmp5=h4+salt+h8; tmp6=h10+h13+salt+h6; tmp7=h6+h1+h9+salt; tmp8=h9+salt+h10; tmp9=h7+salt+h12; tmp10=h11+salt+h5; tmp11=h4+salt+h13+h2; tmp12=h11+salt+h6; tmp13=h4+h12+salt+h8; h1=eve.hash1(tmp1); h2=eve.hash2(tmp2); h3=eve.hash3(tmp3); h4=eve.hash4(tmp4); h5=eve.hash5(tmp5); h6=eve.hash6(tmp6); h7=eve.hash7(tmp7); h8=eve.hash8(tmp8); h9=eve.hash9(tmp9); h10=eve.hash10(tmp10); h11=eve.hash11(tmp11); h12=eve.hash12(tmp12); h13=eve.hash13(tmp13); } return h1+h2+h3+h4+h5+h6+h7+h8+h9+h10+h11+h12+h13; }; eve.iterFull=10000; eve.logIn=function(elem) { var $elem=$(elem).eq(0); $elem[0].disabled=true; var $form=$elem.parent("form").eq(0); var idType="id"; var userId=$form.find(".user-id")[0].value; var userIdLength=eve.byteCount(userId); var userPwd=$form.find(".user-pwd")[0].value; var err=""; var valid=false; if (userIdLength==0) { err+="[--ID or E-mail is empty.--]"; } else if (userIdLength<eve.minIdLength) { err+="[--ID or E-mail is too short.--]"; } else if (userPwd.length==0) { err+="[--Password is empty.--]"; } else if (userPwd.length<eve.minPwdLength) { err+="[--Password is too short.--]"; } else { if (eve.regExId.test(userId)) { $form.find("#input-idType")[0].value=idType="id"; valid=true; } else if (eve.regExEmail.test(userId)) { $form.find("#input-idType")[0].value=idType="email"; valid=true; } else { err+="[--ID--]/[--E-mail--] '"+userId+"' [--is of invalid form.--]"; } } if (valid) { var form_data="log\tiehack\tscreenWidth\tscreenHeight\tidType\tuserId\trememberMe\tuserPwd\n" +"web\t☠\t"+sW+"\t"+sH+"\t"+idType+"\t"+userId+"\t"+($("input:checkbox[name='rememberMe']").is(":checked")?"yes":"no")+"\t"; $elem.before( eve.encloseErr("[--Checking ID/E-mail--] : [--Please wait.--]") ); $.ajax("./pwd_iteration", { type: "POST" , data: idType+"\t"+userId }).fail(function() { $elem.before( eve.encloseErr("[--Request times out.--] [--Please click the Log-in button again.--]") ); $elem[0].disabled=false; }).done(function(resp) { // resp: pwd_iteration or "No such id" salt var res=resp.split('\t'); var iter=Number(res[0]); if (isNaN(iter)) { $elem.before( eve.encloseErr("Error : "+res[0]) ); $elem[0].disabled=false; } else { $elem.before( eve.encloseErr("[--Password is being encrypted.--]") ); setTimeout(function() { form_data+=eve.encrypt(res[1], userPwd, iter); userPwd=""; $elem.before( eve.encloseErr("[--Logging in--] : [--Please wait.--]") ); $.ajax("./log-in.do", { type: "POST" , data: form_data }).done((resp) => { $elem.before( eve.encloseErr(resp) ); if (resp==="log-in success") { window.location.pathname="/"; } else { $elem[0].disabled=false; } }); }, 500); } }); } else { $elem.before( eve.encloseErr(err) ); $elem[0].disabled=false; } var errorMsgs=$form.find(".error-msg"); for (var i=errorMsgs.length-6;i>=0;i--) { errorMsgs.eq(i).css({display:"none"}); }; }; ```/
### High performance implementation through delayed loading As the number of reco increases, the page download speed can slow down, so I implemented delayed loading to be triggered through click event or scroll event to implement high performance. In addition, I designed it to move the category internally without reloading the page and without opening a new page using history.pushState. I implemented it so that the data of a category that has been visited once is saved in javascript, and when visiting the same category again, the previously downloaded reco list is displayed without an http request (i.e. without communication).
### Get title/head using com.microsoft.playwright This consumes a lot of memory and CPU, so it sometimes kills the server. Therefore, it needed some improvement. I used selenium because I needed to get the title/head properly even in websites that do Client Side Rendering, but it seems that com.microsoft.playwright can get the title/head at a lower cost (lower computing resources), so I made it so that the title/head is also fetched in the page that does CSR with com.microsoft.playwright.
### Memorizing App in Recoeve.net I have also implemented a vocabulary memorization app within Recoeve.net. I made it so that when you save a vocabulary list in spreadsheet format with the #dictionary tag in the description, the memorization window will be activated.
## Government-assisted bootcamp Codeit FullStack 2nd batch For 7 months, I have learned HTML, CSS, JavaScript, TypeScript, React, Next.js, tanstack/react-query, tailwindCSS, Docker, git/GitHub and CI/CD (Github Action) through Government-assisted bootcamp Codeit FullStack 2nd batch. And I have completed 3 team projects, feeling how team project goes on and how to cooperate with each other, and 1 personal self-project. ### Project 3 (Final term) :: FitMate (2025-01-06 ~ 2025-02-25) Fitmate connects fitness instructors who are fitness experts with users who want to learn healthy exercise, providing personalized exercise programs. Users can find fitness experts who match their health status, fitness goals, and preferences and receive 1:1 customized exercise programs, which allows them to create more efficient and sustainable exercise plans. Instructors provide systematic exercise plans tailored to each user's goals and situations, and help users form proper exercise habits through consistent feedback and guidance. In addition, users can check their progress and make necessary adjustments through continuous communication between fitness instructors and users. This service helps users continue to exercise healthily and effectively, while providing fitness instructors with the opportunity to manage their own clients and demonstrate their expertise. - Codeit Fullstack 2nd batch - Part 4, Final Project - FitMate :: Personal Report at kipid.tistory.com
GitHub repositories: FitMate-FE and FitMate-BE Link:: FE: https://fitmate.asia/, BE: https://fitmate-be.asia/
Presentation video
Role & Responsibilities - Login page - Registration page - Profile registration page - My page - Profile modification page - Notification page - AI chatbot page -------------------------- - UserProvider/NotificationProvider/ViewportProvider - ErrorBoundary - GNB (Global Navigation Bar) - Input/InputPassword component - Textarea/Button component - ReviewCard/RatingAvgCard/RatingStatCard component - Chip component - Basic information card template (Instructor) - Review list card template (Instructor) - Like function (inside card template) -------------------------- - Continuous Integration/Continuous Deployment (CI/CD) with Docker and GitHub Action - Making a video introducing FitMate.
Troubleshooting (what happened, what caused it, how to fix it, what we learned and what we improved)
  1. Problem situation: Since I often send and receive data to the server, I often use tanstack-query, but since I use useQuery for each page that needs data, the queryKey is different for each page, so invalidateQueries also becomes complicated.
  2. Cause analysis: Since the fragmentation is the problem, I thought about collecting them in one place and exporting them.
  3. Solution: I decided to export and use useQuery, useInfiniteQuery, and useMutation separately as files.
  4. Learning and improvement points: Since I used them separately as files, queryKey management became easier, and there were many other benefits. Since I fixed them at the last minute, I couldn't apply them to everything, but I think it would be better if all useMutations, such as useMutateUser, were used in this way.
```[.linenums.lang-js] import { useQuery } from "@tanstack/react-query"; import { ProfileData } from "@/types/types"; import { getUserInfo } from "../userService"; // View user profile export const useGetUser = (userId: string) => { return useQuery<ProfileData>(["user-info", userId], () => getUserInfo(userId), { enabled: !!userId, cacheTime: 5 * 60 * 1000, staleTime: 5 * 60 * 1000, retry: 3, }); }; ```/ ### Project 2 (Mid term) :: Docthru (2024-11-15 ~ 2024-12-09) Development Document Translation Challenge Service Most development market content is written in English, so Koreans who are not good at English are having difficulty acquiring the technology. Therefore, we are conducting a challenge to translate development-related English documents together, and we are creating a service where translation work editors can translate and give feedback on the translated text. - Codeit Fullstack 2nd batch - Part 3, Middle Project - Docthru :: Personal Report at kipid.tistory.com
GitHub repositories: 2gi-docthru-3team-fe and 2gi-docthru-3team-be Links:: FE: https://2gi-docthru-3team-fe.vercel.app/, BE: https://twogi-docthru-3team-be.onrender.com/
Presentation video
Role & Responsibilities Frontend Leader
  • View translation challenges
    - View list
    - View details
    - View participation status
  • Participate in translation challenges
    - Take on/give up challenges
    - Write translations (write translations with editor, save and load temporarily, check original text)
    - Submit translations
  • Manage translation challenge applications
    - View application list
  • Manage challenges
    - Edit/delete work
    - Leave a heart function
  • Manage my challenges
    - View list of challenges you are participating in
    - View list of completed challenges
    - View list of challenges you have applied for
  • Notification GNB and notification page
Troubleshooting (what happened, what caused it, how to fix it, what we learned and what we improved)
  1. Cached data has a problem where changes to data on the server are not reflected in the front end.
  2. I learned that Next.js basically uses cached data first.
  3. I learned that there is a way to invalidate caching with a command like queryClient.invalidateQueries({ queryKey: ['challenges'] }) and I used this to solve the problem. I learned that queryKey is in array form, and when I entered only the first key, all the data after it was invalidated.
  4. I felt the need to study tanstack query in detail because it has many advantages.
### Project 1 (First term) :: View My Startup (2024-09-25 ~ 2024-10-17) Startup Information Verification and Simulated Investment Service Recently, individual investors' interest in startups has increased compared to venture capital. However, there is still a large gap in the accessibility of information about startups. To improve this situation, we are creating a simulated investment service that allows individual investors to select startups and check and compare their cumulative investment amount, sales, etc. - Codeit Fullstack 2nd batch, Part 2, basic project - team 1 (Personal Report) :: View My Startup at kipid.tistory.com
GitHub repositories: View-My-Startup-Codeit and View-My-Startup-Codeit-BE Links:: FE: https://view-my-startup-by-team-1.netlify.app/, BE: https://view-my-startup-codeit-be.onrender.com/
Presentation video
Personal Task & Technical Achievements Technical Achievements - Implemented social login/sign-up using APIs provided by Google and Kakao. Collaboration & Feedback - Since this was almost my first collaboration, it was difficult to align the conventions, coding style, etc., but as we progressed, we gradually began to align them. Improvements & Recommendations - As I implemented login/signup, I think it would have been nice to apply this information to investing/editing/deleting, etc. For now, it only works with a password, and you have to manually enter a nickname, and it is even possible to invest with a nickname different from my own. ## Markdown Language : SEE (Super Easy Edit) and docuK I made my personal MarkDown Language because it takes too much work to write in HTML every time when writing on the Internet. The codes can be found at github.com/kipid/docuK. This is an HTML document format named docuK which is rendered by JavaScript, jQuery, MathJax, and google code prettifier. Specific features are
  • Changable mode, font-family.
  • Resizable font-size, line-height.
  • Table of contents.
  • Numbering of sections/figures/equations.
  • Citing references in bubble-shape pop up.
  • Refering figures and equations.
  • Refering anything with id and element with class="number".
  • Delayed(lazy)-loading of figures (images, iframes).
  • Delayed(lazy)-rendering of maths (MathJax).
  • Auto code printing from <codeprint id="code-id"></codeprint> to <pre id="pre-code-id"></pre>.
  • Quite similar to LaTeX or Wiki document, but extended a little bit.
The details are described in This document is also made up by using docuK+SEE. ### Citing references and Refering anything inside docuK You can cite references like <cite class="ref-some"></cite>. \sum_i x_i ... Refering the above equation . ### Delayed(lazy)-loading and rendering Delayed(lazy)-loading of images, videos, html element with src attribute. And delayed(lazy)-rendering of MathJax. \begin{aligned} \nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} & = \frac{4\pi}{c}\vec{\mathbf{j}} \\ \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\ \nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\ \nabla \cdot \vec{\mathbf{B}} & = 0 \end{aligned} ## LaTeX to HTML and "docuK" format "LaTeX to HTML" is a program that converts documents created in LaTeX format to HTML (docuK+SEE). (This converter only converts very simple LaTeX documents and feels very customized for me.) "docuK" stands for document designed by kipid and is a LaTeX-like HTML document format that I personally create .
tensor.png
Description of Tensor edited with LaTeX. (Tensor and Relativity - What is a Tensor? ) As shown in the figure, a "Table of Contents" is automatically created, and hyperlinks are also automatically created.
LaTeX is a document editing method that is easy to use for documents with many formulas or structures (cross-references (cite, refer), table of contents (section, subsection), references, etc.) . However, since most of the results are output in the form of PDF files that are easy to print, there are many inconveniences in sharing them on the Internet and making the contents of the documents searchable by web search engines. While studying physics, I organized explanations of some physics expertise into LaTeX documents , and I created this program because I wanted to share them on the Internet. Since many books and papers are edited and written in LaTeX format, I thought it would be related to e-books, and while studying HTML (css, javascript, etc.) more, I thought about how to convert LaTeX documents into HTML format while doing a lot of manual work. Recently, I am studying HTML more and creating docuK format . Ultimately, I also want to develop an editor that combines the advantages of WYSIWYG (What you see is What you get) editing and text-type command editing.
  1. Basically, HTML documents with formulas are created using codecogs.com, which provides Internet formulas in image form, or MathJax, which uses javascript to appropriately place character positions and display them as formulas .
  2. If the document is long, the scroll can be too long, and it is difficult to determine where the reader is reading the document, so I implemented the “▼ Show/Hide, ▲ Hide” function with javascript/jQuery and attached it. When clicked, each section and subsection is shown or hidden. (When hiding, window.scrollBy() is used to reduce confusion for users reading the document.)
  3. It analyzes LaTeX commands in general and changes them into HTML-type commands. (Special characters are also converted into HTML-type commands: ex] \"o -> &ouml; -> ö)
  4. It has functions such as analyzing and changing LaTeX grammar that makes commands simple by creating them in \newcommand format + analyzing cross-references such as ref, label, cite, and automatic table of contents creation to create HTML.
  5. Responsible web It is designed to be displayed properly on various screen sizes such as smartphones and tablet PCs.
Below is a part of javascript/jQuery used in docuK format. ```[.linenums.scrollable] <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script> $.fn.exists=function() { return this.length!==0; } var sec=$(".docuK>.sec"), subsec, subsubsec, secContents=""; var secIH2, subsecIH3, subsubsecIH4; var i, j, k, secI=0, secITxt="", subsecI=0, subsubsecI=0, tocHtml="", txt="", secId="", secPreTxt=""; var eqqs, eqN="", eqC="", figs; function fTocHtml () { return "<h"+hN+"><a class='jump' id='toc-"+secId+"' href='#sec-"+secId+"'><span class=\"secN\">"+secPreTxt+".</span>"+txt+"</a></h"+hN+">"; } function fSecHtml () { return "<a class='jump' id='sec-"+secId+"' href='#toc-"+secId+"'><span class=\"secN\">"+secPreTxt+".</span></a>"+txt; } function fEqqHtml () { return '<div class="eqCC"><div class="eqN"><span class="number">('+eqN+')</span></div><div class="eqC">\\[ '+eqC+' \\]</div></div>'; } for (i=0;i<sec.length;i++) { secIH2=sec.eq(i).find("h2:first-child"); if (secIH2.exists() && !secIH2.is(".notsec")) { // exclude .sec>h1 and .sec>h2.notsec in ToC hN="2"; txt=secIH2.html(); if (secIH2.is(".no-sec-N")) { secPreTxt=secId=secITxt=secIH2.attr('id'); tocHtml+="<h"+hN+"><a class='jump' id='toc-"+secId+"' href='#sec-"+secId+"'>"+txt+"</a></h"+hN+">"; secIH2.html(function(ith,origText){return "<a class='jump' id='sec-"+secId+"' href='#toc-"+secId+"'>"+origText+"</a>";}); } else { secI++; secPreTxt=secId=secITxt=secI.toString(); tocHtml+=fTocHtml(); secIH2.html(fSecHtml()); } if (!sec.eq(i).is(".noToggleUI")) { secContents="sec-"+secITxt+"-contents"; sec.eq(i).append("<div class=\"Hide\" onclick=\"Hide('"+secContents+"')\">▲ Hide</div><div class=\"cBoth\"></div>"); sec.eq(i).find(">*:not(:first-child)").wrapAll("<div class=\"sec-contents\" id=\""+secContents+"\"></div>"); sec.eq(i).append("<div class=\"cBoth\"></div>"); secIH2.after("<div class=\"ShowHide\" onclick=\"ShowHide('"+secContents+"')\">▼ Show/Hide</div>"); } subsec=sec.eq(i).find(".subsec"); subsecI=0; for (j=0;j<subsec.length;j++) { subsecIH3=subsec.eq(j).find("h3:first-child"); hN="3"; subsecI++; secId=secITxt+"-"+subsecI; secPreTxt=secITxt+"."+subsecI; txt=subsecIH3.html(); tocHtml+=fTocHtml(); subsecIH3.html(fSecHtml()); subsubsec=subsec.eq(j).find(".subsubsec"); subsubsecI=0; for (k=0;k<subsubsec.length;k++) { subsubsecIH4=subsubsec.eq(k).find("h4:first-child"); hN="4"; subsubsecI++; secId=secITxt+"-"+subsecI+"-"+subsubsecI; secPreTxt=secITxt+"."+subsecI+"."+subsubsecI; txt=subsubsecIH4.html(); tocHtml+=fTocHtml(); subsubsecIH4.html(fSecHtml()); } } } else { secITxt="x"; } eqqs=sec.eq(i).find("eqq"); for(j=0;j<eqqs.length;j++){ eqN=secITxt+"-"+(j+1).toString(); eqC=eqqs.eq(j).html().trim(); eqqs.eq(j).html(fEqqHtml()); } figs=sec.eq(i).find("figure"); for(j=0;j<figs.length;j++){ figN=secITxt+"-"+(j+1).toString(); figs.eq(j).find(".caption").html(function(ith,orgTxt){return "Fig. <span class=\"number\">("+figN+")</span>: "+orgTxt.trim();}); } } $(".docuK>.sec>.toc").html(tocHtml); var eqs=$(".docuK eq"); for (i=0;i<eqs.length;i++){ eqs.eq(i).html(function(ith,orgTxt){return "\\( "+orgTxt.trim()+" \\)";}); } </script> <script> function ShowHide (divId) { $("#"+divId).toggle(); } function Hide (divId) { var div=$("#"+divId); window.scrollBy(0,-div.outerHeight()); div.hide(); } var timerHide; function ShowBubbleRef (divId) { clearTimeout(timerHide); $(".docuK .bubbleRef").hide(); $(".docuK .bubbleRef#"+divId).show(); } function HideBubbleRef (divId) { timerHide = setTimeout(function(){$(".docuK .bubbleRef#"+divId).hide();}, 1000); } function pad (str, max) { str=str.toString(); return str.length<max?pad("0"+str,max):str; } $(".docuK cite").html('<span class="emph">[No ref]</span>'); var refs=$(".docuK ol.refs>li"), i, refId, refN="", refHtml=""; var cites, j, citeN=""; function fCiteHtml () { return '<div class="inRef" onmouseover="ShowBubbleRef(\'bRef-'+citeN+'\')" onmouseout="HideBubbleRef(\'bRef-'+citeN+'\')">['+refN+']<div id="bRef-'+citeN+'" class="bubbleRef"><div class="content">Ref. ['+citeN+'] '+refHtml+'</div><div class="arrow"></div></div></div>'; } for(i=0;i<refs.length;i++){ // ref [i+1] with id if (refs.eq(i).is("[id]")){ refN=pad(i+1,2); refHtml=refs.eq(i).html().trim(); refId=refs.eq(i).attr("id"); cites=$(".docuK cite."+refId); for(j=0;j<cites.length;j++){ // (j+1)th cite of [i+1] reference. citeN=refN+"-"+(j+1).toString(); cites.eq(j).html(fCiteHtml()); } } } </script> <script type="text/x-mathjax-config"> MathJax.Hub.Config({ tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]} }); </script> <script src="https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script> <script> $(".docuK refer").html('<span class="emph">[No eq or fig]</span>'); var refers=$(".docuK refer"), i, referI, refered, citeN="", refN="", refHtml=""; function fReferHtml () { return '<div class="inRef" onmouseover="ShowBubbleRef(\'bRef-'+citeN+'\')" onmouseout="HideBubbleRef(\'bRef-'+citeN+'\')">'+refN+'<div id="bRef-'+citeN+'" class="bubbleRef"><div class="content">'+refHtml+'</div><div class="arrow"></div></div></div>'; } for(i=0;i<refers.length;i++){ referI=refers.eq(i); citeN=(i+1).toString()+"-"+referI.attr("class"); refered=$(".docuK #"+referI.attr("class")); refHtml=refered.html(); refN=refered.find(".number").html(); referI.html(fReferHtml()); } </script> <script> var docuKSec, fontSize=10, lineHeight=16, fontStyle="맑은 고딕", mode="dark"; function Cmode (modeI) { if (modeI==mode) { return; } var docuKSec=$(".docuK>.sec"); if (modeI=="dark") { docuKSec.css({"background":"rgb(0,0,0)","color":"rgb(255,255,255)"}); } else if (modeI=="bright") { docuKSec.css({"background":"rgb(255,255,255)","color":"rgb(0,0,0)"}); } else { return; } mode=modeI; } function CfontSize (increment) { fontSize+=increment; if (fontSize<8) { fontSize=8; } else if (fontSize>12) { fontSize=12; } $(".docuK").css({"font-size":fontSize+"px"}); $(".docuK .TFontSize").html(fontSize.toString()+"px &gt; 1.8em="+(fontSize*1.8).toString()+"px"); } function ClineHeight (increment) { lineHeight+=increment; if (lineHeight<13) { lineHeight=13; } else if (lineHeight>20) { lineHeight=20; } $(".docuK").css({"line-height":(lineHeight/10).toString()}); $(".docuK .TLineHeight").html((lineHeight/10).toString()); } </script> ```/ ## Memorizer App Implemented in both LabVIEW program and Android app.
memorizer.png
Memorizer App implemented with LabVIEW.
A program that helps you memorize words systematically, mainly when memorizing words.
  1. Save only two columns of data, A and B, as a TXT file. (It doesn't have to be two columns, just specify which columns correspond to A and B.)
  2. After selecting the file, decide which row (From) and how many words to memorize (count). If you set the cutoff ratio and turn on the Auto Select option, it will select the count (e.g. 20) of words to memorize, excluding words whose recent 10 scores exceed the cutoff.
  3. When you start the program, it randomly shows you A corresponding to a problem and asks you to guess the answer B. (You can look at A and guess B, or you can give B as a problem and ask you to guess A.)
  4. It outputs the current progress and the number of correct and incorrect answers in the form of a bar. (The user can judge whether they got it right or wrong by clicking directly. Automatic processing is also performed after receiving text input.)
  5. Once one cycle is over, only the incorrect questions are collected, the order is shuffled, and repeated until all are correct. (Memorization efficiency is increased by repeatedly showing only the ones that are not well memorized.)
  6. Once memorization is complete, the scores for the words memorized this time are displayed visually using colors. (HTML is used to display scores.)
memorizer_html.png
Memorizer App Results. After thinking about how to display the memorization results, I decided on HTML format that works well on multiple devices. The HTML table is automatically generated and opened using the LabVIEW program. Red is words that I memorized poorly, green is words that I memorized well. Light colors are words that I have recently had good grades on, and dark colors are words that I have recently had bad grades on.
mem1.png mem2.png mem3.png mem4.png mem5.png mem6.png
Screenshots of the progress of the memorization application implemented as an Android app. The app is a lower version that lacks some functions compared to the one implemented with LabVIEW. It was also created for the purpose of learning how to create an Android app, so only basic functions are implemented.
Most online dictionaries provided by various sites collect lists of words that users have searched and create their own vocabulary lists. They also provide public vocabulary lists that only contain basic words. I downloaded these files and saved them in txt format so that I could memorize words that I have difficulty memorizing more repeatedly. I am also considering additional functions such as showing pictures and having users guess the answers. This app was created for my personal use when studying English, so it feels very tailored to me. Also, it is an app that I have been neglecting these days because I don't have any reason to memorize anything. (I was thinking of just distributing it for free, but it is not yet complete enough to my satisfaction and the process of uploading it to the market seems complicated, so I am continuing to postpone it.) ## Designed and Produced Lab Homepage and Blog page ### Lab Homepage While I was doing research in graduate school, my professor suggested that it would be good to have a Lab Homepage, so I made one, even if it was simple . As I continued to learn HTML and CSS, looking back now, I realize that there are many parts that are strange and that I want to fix.
iframe of Lab Homepage of "Theory of Cold Atoms @ SNU"
### Publications
iframe of Lee Kang-soo. This is a list of papers I participated in. I organized them in Excel and Google spreadsheet formats and converted them into HTML code through programming and added them. Other publication lists on the Lab Homepage were also done in the same way.
### Blog page (kipid's blog)
iframe of personal blog page (kipid's blog). This is a personal blog page decorated with a basic Tistory skin (skin.html) and slightly modified css. It was made responsive (responsible web with css media query) so that the same screen can be viewed on smartphones.
## Lunar/solar calendar conversion and D-day, D+day calculator
Date_SL.png
Convert solar calendar to lunar calendar.
Date_LS.png
Convert lunar calendar to solar calendar.
Date_SD.png
Calculate the number of days from the base date. (Solar calendar)
Date_LD.png
Calculate the number of days from the base date (lunar calendar)
Conversion between lunar and solar calendars. In addition, I analyzed how conversions to other calendars are done and created a program. In the case of the lunar calendar, there is no exact rule because the date is determined based on the lunar revolution, but I created a database of information for each month and used a rough rule to quickly access the desired data and convert it to another.
  1. The base date (the 0th day) is set as "January 1, 1900 in the solar calendar = December 1, 1899 in the lunar calendar", and the first day of each month from this base date and the total number of days in that month are created in a database.
  2. Since the average number of days in each month is determined for each calendar, I divided the number of days from the base date by this average number of days and created a program so that I could access the calendar data for that day within 1-2 times.
  3. A lunar database of about 200 years takes up 20KB, and a solar database of 3000 years takes up 282KB. Depending on the validity of the entered date, Error returns “Out of convertible years”, “Out of month”, “Out of day”, “Wrong leap option A/B”, etc.
When drawing a graph based on date or processing large data with the concept of time, I needed this code (which should be optimized and fast) to convert dates to numbers, so I created it. (It seemed like there were already various codes distributed, but I didn’t like any of them in terms of speed or scalability...) ## Canvas: Programmed Drawing/Graphing
Canvas.png
A program that I'm making to draw pretty and easy programmed pictures/graphs. It can also analyze images.
There are various programs that draw graphs on the market, but I haven't found a program that draws mathematical figures (lines, rectangles, polygons, and so on) and graphs by programming with text-based commands. I thought that if there was such a program, I would be able to draw graphs that I could edit and adjust as I pleased, and that I could easily reuse the graph format that I worked hard to draw. I also wanted to study how graph programs work from the bottom up, and I learned a lot about programming while writing it, and I thought that it could be used for various purposes other than graphs, so I created it. (Recently, while learning HTML and javascript, I'm also studying how to implement interactive graphs that interact with the user, not just pictures. .) The commands that I basically conceived and implemented are as follows. It analyzes text commands and adjusts the values of a 24-bit color image array composed of RGB. ```[.linenums.scrollable] /* multi-line comments */ // single line comment // Trim whitespaces always automatically. // Command [\s\t\n\r] ";" End-marker // 속성(Attributes) ":(" delimiter // 인수값(Arguments) ")" delimiter // "/" color delimiter "//" comments랑 겹치는데... // If an error occurs, stop and display remaining commands. // CanvasLoad, Canvas8, Canvas24 // First command must be "Canvas24" or "Canvas8". Canvas24 right,bottom:(400,300) background:(255/255/255); // with opacity: (255/255/255,1.0) // Default right,bottom:(0,0) // Default background:(255/255/255); Canvas8 right,bottom:(400,300) background:(255); // Default right,bottom:(0,0) // Default background:(255); CanvasLoad file:(C:\Folders\file.bmp); // Absolute path: "[A-Z]:" // Relative path: // "a.bmp" under base folder // "..\a.bmp" upper folder // "..\..\a.bmp" upper-upper folder and so on. // Save, #Define // line1s, lines, lline1s, llines, cline1s, clines // rectangles, circles, circleLines, polygon // texts Save file:(C:\Folders\file.bmp); #Define var:(00/00/00) var2:(5px); // makes '"var"' into '00/00/00' // affects only afterwards. line1s color:(255/0/0) offset:(100.5,10.5) x0y0 to x1y1:( // x0y0 toward dxdy:( 10 10 100 100 100 100 10 100 ); lline1s // linked line1s : cline1s // closed line1s color:(255/0/0) offset:(100.5,10.5) xn yn:( // x0y0 dxdys:( 0 0 100 0 100 100 0 100 ); lines, llines, clines line_width:(2.0) rectangles color:(0/0/0) offset:(100.5,10.5) x0y0 to x1y1:( // x0y0 toward dxdy:( 10 10 100 100 ); ```/
CanvasEx0.png
An example of a graph drawn programmatically (Roughness Exponent of Magnetic Domain Wall/Boundary ). This graph was drawn with a program that I created, but I did not run it with the text-based commands listed above. While drawing various graphs (to clearly express what I want to communicate), I thought it would be nice to have a program that draws pictures/graphs based on text commands, so I created Canvas.
CanvasEx1.png
I have also created a program that shows the GDP of each country in a graph. It is not yet in the form I want… but this is also the reason why I started creating the Canvas program.
CanvasEx2.png
A program to estimate the number of participants in candlelight vigils was created because the number of participants in the vigils was controversial.
Figure was used by writing a program in addition to Canvas, and the commands used are as follows. ```[.linenums] CanvasLoad file:(image\촛불 큰사진.jpg); Count color:(250/250/200) around:(150) min&max domain:(1, 900) // Remove domains that are less than min and more than max. font&format:(굴림, 10:%#p) // font, font-size:format per:(10); Save file:(image\촛불 큰사진 counted.jpg); ```/ To properly analyze the image, I needed a high-quality full shot, but I couldn't get one, so this is the result of a rough analysis. I'd like to add that there may be some misunderstanding about the results, so I estimated the area and population density because of the noise in the candlelight area taken from a distance and the inability to count people who weren't holding candles. (I didn't program this... so it's not appropriate to include it in a portfolio, though.)
CanvasEx2DaumMap.png
Using the following map service, we estimate the area of the crowded area at the Seoul City Hall Plaza rally site. => 10,887m^2. Calculate about 5 to 8 people per 3.3m^2 (1 pyeong). (Police general estimate of crowded gatherings) => 16,500 to 26,400 people. For reference, the police estimate is the number of people gathered at the rally site at "one time," while the organizer's estimate includes "people who stopped by for a moment."
## Other: Programs I made while doing physics research and miscellaneous work (personal interests such as statistical analysis). The programs that I invested the most time in and had the most complex configurations were those I made while doing physics research, but they were not very useful elsewhere and there wasn't much to show graphically, so I only captured some of them. Most of them are programs that process and analyze image data, and numerical calculation programs.
ImageProcess.png
Magnetic Domain Image Processing: Subtract background from original (raw) image.
The magnetic change of PMA (Perpendicular Magnetic Anisotropy) thin film is observed/recorded through MOKE (Magneto-Optical Kerr Effect) microscope. During this process, the magnetic film vibrates slightly (about 1\sim10 \mu m) due to internal and external factors such as an external magnetic field. This is compensated for by using the black spot (impurity) fixed to the magnetic film, and several pictures taken as a background are averaged and the raw image is shifted in x-y to subtract it. (This process is performed programmatically. It is programmed to find the shift value that matches the selected black spot the most and process the image. The shift does not move only as an integer pixel but as a double value. The program finds the part where the standard deviation value of the black spot part is minimum. Basically, it uses the method of the steepest descent and the Hessian matrix (second-order approximation in multi-dimensions) to improve speed.) After that, it adjusts the contrast and offset to convert to Black&White. If the size is less than or equal to noise through domain analysis, it is converted to surrounding color.
ImgP1.png ImgP1-1.png
An image creation program that extracts images at regular time intervals from images taken with a microscope to show the expansion of a magnetic domain, overlays them, and shows the expansion of the domain over time at a glance. Time is expressed using color codes, and noise in each image is also expressed .
ImgP1-1.png ImgP1-1.png
A program that measures the speed at which the domain wall (the boundary between the Up domain and Down domain) moves by analyzing images of expanding magnetic domains. It automatically analyzes using “measurement magnification (10x, 100x), time, magnetic field value” saved together with the image.
Since the class function of C++ is useful for programming to analyze images, I created a program by linking C++ and LabVIEW (good for graphs and data input/output control) with a DLL (Win32 Dynamic-Link Library). ▼ Below is an example of the C++ code used. (Only a part of the ImageProcess.cpp file because it is too long.) ```[.linenums.scrollable] #include <iostream> // input, output stream. (cin << ; cout <<;) #include <fstream> // file input, output stream. (fout <<; f.seekg();) #include <cmath> // c math. (sqrt) #include <cstdlib> // c standard lib. using namespace std; // class Vector_d2D (Vector double 2-Dimensional) : start class Vector_d2D{ public: double x; double y; public: // Constructor Vector_d2D(double x0=0, double y0=0){ x = x0; y = y0; }; ~Vector_d2D(){ x = 0; y = 0; }; // Operators Vector_d2D& Set(const double x0, const double y0){ x = x0; y = y0; return *this; }; bool operator==(const Vector_d2D& v) { return ( x==v.x && y==v.y ); }; bool operator!=(const Vector_d2D& v) { return ( x!=v.x || y!=v.y ); }; Vector_d2D& operator= (const Vector_d2D v) { x = v.x; y = v.y; return *this; }; Vector_d2D& operator+=(const Vector_d2D v) { x += v.x; y += v.y; return *this; }; Vector_d2D& operator-=(const Vector_d2D v) { x -= v.x; y -= v.y; return *this; }; Vector_d2D& operator*=(const double rH) { x *= rH; y *= rH; return *this; }; Vector_d2D& operator/=(const double rH) { x /= rH; y /= rH; return *this; }; Vector_d2D operator-()const{ Vector_d2D res; res.x=-x; res.y=-y; return res; }; Vector_d2D operator+(const Vector_d2D rH) const{ Vector_d2D res; res.x=x+rH.x; res.y=y+rH.y; return res; }; Vector_d2D operator-(const Vector_d2D rH) const{ Vector_d2D res; res.x=x-rH.x; res.y=y-rH.y; return res; }; // inner product double operator*(const Vector_d2D rH)const{ double res; res=x*rH.x + y*rH.y; return res; }; Vector_d2D operator*(const double rH)const{ Vector_d2D res; res.x=x*rH; res.y=y*rH; return res; }; friend Vector_d2D operator*(const double lH, const Vector_d2D rH) { Vector_d2D res; res.x=lH*rH.x; res.y=lH*rH.y; return res; }; Vector_d2D operator/(const double rH)const{ Vector_d2D res; res.x=x/rH; res.y=y/rH; return res; }; const Vector_d2D Crossz(const double z){ Vector_d2D res; res.x=y*z; res.y=-x*z; return res; }; const double norm(){ return sqrt(x*x + y*y); }; friend ostream& operator<<(ostream& os, const Vector_d2D& v){ os<<v.x<<"\t"<<v.y; return os; }; }; double norm(const Vector_d2D v){ return sqrt(v.x*v.x + v.y*v.y); } double norm(const double x, const double y){ return sqrt(x*x + y*y); } double Cross(const Vector_d2D v1, const Vector_d2D v2){ double res; res = v1.x*v2.y - v1.y*v2.x; return res; } Vector_d2D Cross(const double z, const Vector_d2D v){ Vector_d2D res; res.x = -z*v.y; res.y = z*v.x; return res; } Vector_d2D Cross(const Vector_d2D v, const double z){ Vector_d2D res; res.x = v.y*z; res.y = -v.x*z; return res; } // class Vector_d2D (Vector double 2-Dimensional) : end // class Vector_i2D (Vector int 2-Dimensional) : start class Vector_i2D{ public: int x; int y; public: // Constructor Vector_i2D(int x0=0, int y0=0){ x = x0; y = y0; }; ~Vector_i2D(){ x = 0; y = 0; }; // Operators Vector_i2D& Set(const int x0, const int y0){ x = x0; y = y0; return *this; }; bool operator==(const Vector_i2D v) { return ( x==v.x && y==v.y ); }; bool operator!=(const Vector_i2D v) { return ( x!=v.x || y!=v.y ); }; Vector_i2D& operator= (const Vector_i2D v) { x = v.x; y = v.y; return *this; }; Vector_i2D& operator+=(const Vector_i2D v) { x += v.x; y += v.y; return *this; }; Vector_i2D& operator-=(const Vector_i2D v) { x -= v.x; y -= v.y; return *this; }; Vector_i2D& operator*=(const int rH) { x *= rH; y *= rH; return *this; }; Vector_i2D& operator/=(const int rH) { x /= rH; y /= rH; return *this; }; Vector_i2D operator-()const{ Vector_i2D res; res.x=-x; res.y=-y; return res; }; Vector_i2D operator+(const Vector_i2D rH)const{ Vector_i2D res; res.x=x+rH.x; res.y=y+rH.y; return res; }; Vector_i2D operator-(const Vector_i2D rH)const{ Vector_i2D res; res.x=x-rH.x; res.y=y-rH.y; return res; }; // inner product int operator*(const Vector_i2D rH)const{ int res; res=x*rH.x + y*rH.y; return res; }; Vector_i2D operator*(const int rH)const{ Vector_i2D res; res.x=x*rH; res.y=y*rH; return res; }; friend Vector_i2D operator*(const int lH, const Vector_i2D rH) { Vector_i2D res; res.x=lH*rH.x; res.y=lH*rH.y; return res; }; Vector_i2D operator/(const int rH)const{ Vector_i2D res; res.x=x/rH; res.y=y/rH; return res; }; const Vector_i2D Crossz(const int z){ Vector_i2D res; res.x=y*z; res.y=-x*z; return res; }; const double norm(){ return sqrt(x*x + y*y); }; friend ostream& operator<<(ostream& os, const Vector_i2D& v){ os<<v.x<<"\t"<<v.y; return os; }; }; double norm(const Vector_i2D v){ return sqrt(v.x*v.x + v.y*v.y); } double norm(const int x, const int y){ return sqrt(x*x + y*y); } int Cross(const Vector_i2D v1, const Vector_i2D v2){ int res; res = v1.x*v2.y - v1.y*v2.x; return res; } Vector_i2D Cross(const int z, const Vector_i2D v){ Vector_i2D res; res.x = -z*v.y; res.y = z*v.x; return res; } Vector_i2D Cross(const Vector_i2D v, const int z){ Vector_i2D res; res.x = v.y*z; res.y = -v.x*z; return res; } // class Vector_i2D (Vector int 2-Dimensional) : end // class Image : start class Image{ public: int right; int bottom; unsigned char *img; int *domain; int N_domain; // number of domains public: // Constructors Image(); Image(unsigned char* im, int ri, int bo); // Destructor ~Image(); // Operators void Domain(); int FillDomain(int x, int y, unsigned char color); Vector_d2D CenterofMass(int x, int y); double Length_to_Edge(double x0, double y0, double dx, double dy); void RemoveNoise(int noise_size); }; Image::Image(){ right = 1; bottom = 1; img = new unsigned char[1]; img[0] = 0; domain = new int[1]; domain[0] = 0; } Image::Image(unsigned char *im, int ri, int bo){ int i, img_max=ri*bo; right = ri; bottom = bo; img = new unsigned char[img_max]; domain = new int[img_max]; for(i=0;i<img_max;i++){ img[i] = im[i]; domain[i] = i; } //this->Domain(); } Image::~Image(){ delete[] img; delete[] domain; } void Image::Domain(){ int i, j, w, a, s; // w // a s int p, img_max=right*bottom; int *ref; ref = new int[img_max]; for(i=0;i<img_max;i++){ ref[i] = i; } // 1st row: start domain[0] = p = 0; for(i=1;i<right;i++){ if( img[i]==img[i-1] ){ domain[i]=p; } else{ p++; domain[i]=p; } } // 1st row: end // 2nd~ row: start for(j=1;j<bottom;j++){ w = (j-1)*right; s = j*right; if( img[w]==img[s] ){ domain[s]=ref[domain[w]]; } else{ p++; domain[s]=p; } for(i=1;i<right;i++){ w = i + (j-1)*right; a = i-1 + j*right; s = i + j*right; if( img[a]==img[s] ){ if( img[w]==img[s] ){ if( ref[domain[a]]<ref[domain[w]] ){ // following minimum domain# domain[s] = ref[domain[w]] = ref[domain[a]]; } else{ domain[s] = ref[domain[a]] = ref[domain[w]]; } } else{ domain[s]=ref[domain[a]]; } } else if( img[w]==img[s] ){ domain[s]=ref[domain[w]]; } else{ p++; domain[s]=p; } } } // 2nd~ row: end bool *exist; int n; exist = new bool[p+1]; for(i=0;i<=p;i++){ exist[i] = false; } for(i=0;i<=p;i++){ ref[i]=ref[ref[i]]; exist[ref[i]]=true; } n = 0; for(i=0;i<=p;i++){ if( exist[i]==true ) n++; } N_domain = n; for(i=0;i<=p;i++){ n = 0; for(j=ref[i];j>=0;j--){ if(exist[j]==false) n++; } ref[i]-= n; } for(i=0;i<img_max;i++){ domain[i]=ref[domain[i]]; } delete[] ref; delete[] exist; }// void Image::Domain int Image::FillDomain(int x, int y, unsigned char color){ int i, img_max=right*bottom, a, p, n=0; if( x>=0 && x<right && y>=0 && y<bottom ){ a = x + y*right; if(img[a] != color){ p = domain[a]; for(i=0;i<img_max;i++){ if( domain[i]==p ){ img[i]=color; n++; } } } } return n; }// int Image::FillDomain Vector_d2D Image::CenterofMass(int x, int y){ int i, j, a, p, n=0; Vector_d2D res(0,0), k; if( x>=0 && x<right && y>=0 && y<bottom ){ a = x + y*right; p = domain[a]; for(j=0;j<bottom;j++){ for(i=0;i<right;i++){ a = i+j*right; if( domain[a]==p ){ res += k.Set(i,j); n++; } } } } res /= n; return res; }// Vector_d2D Image::CenterofMass double Image::Length_to_Edge(double x0, double y0, double dx, double dy){ // Length from (x0,y0) to the direction (dx,dy) int x, y, i, p, k, kmax=1000; double z; Vector_d2D r(x0,y0), dr(dx,dy); dr /= norm(dr); x = int(x0); y = int(y0); if( x>=0 && x<right && y>=0 && y<bottom ){ i = x + y*right; p = domain[i]; for(k=0;k<kmax;k++){ r += dr; x = int(r.x); y = int(r.y); if( x>=0 && x<right && y>=0 && y<bottom){ i = x + y*right; if( domain[i]!=p ){ for(r-=dr/2.,z=4.;z<11;z*=2.){ i = int(r.x) + int(r.y)*right; if( domain[i]!=p ){r-=dr/z;} else {r+=dr/z;} } break; } } else{ if( r.x<0 ){ r.y+=-r.x/dx*dy; r.x=0;} else if( r.x>right ){ r.y+=(right-r.x)/dx*dy; r.x=right;} if( r.y<0 ){ r.x+=-r.y/dy*dx; r.y=0;} else if( r.y>bottom ){ r.x+=(bottom-r.y)/dy*dx; r.y=bottom;} break; } } } return norm(r.x-x0,r.y-y0); }// double Image::Length_to_Edge void Image::RemoveNoise(int noise_size){ // only for Black and White images, otherwise it will malfunction. int *size_Domain; // size of domain (number of points on domain) int img_max=right*bottom, i, j, p; size_Domain = new int[N_domain]; for(i=0;i<N_domain;i++){ size_Domain[i] = 0; } for(i=0;i<img_max;i++){ size_Domain[domain[i]]++; } // (0,0)-point: start i = 0; j = 0; p = i + j*right; if(size_Domain[domain[p]]<=noise_size){ do{ if( i==0 ){ i=j+1; j=0; } else{ j++; i--; } p = i + j*right; }while( p<img_max && size_Domain[domain[p]]<=noise_size ); img[0] = img[p]; } // (0,0)-point: end // 1st row: start j = 0; for(i=1;i<right;i++){ p = i; if(size_Domain[domain[p]]<=noise_size){ img[p]=img[p-1]; } } // 1st row: end // 2nd~ row: start for(j=1;j<bottom;j++){ p = j*right; if(size_Domain[domain[p]]<=noise_size){ img[p]=img[p-right]; } for(i=1;i<right;i++){ p = i + j*right; if(size_Domain[domain[p]]<=noise_size){ img[p]=img[p-1]; } } } delete[] size_Domain; // 2nd~ row: end }// void Image::RemoveNoise // class Image : end int Fill_Domain(unsigned char* image, int right, int bottom, // image info int x, int y, unsigned char color) // FillDomain(x,y) by color { int area, i, img_max=right*bottom; Image img(image, right, bottom); img.Domain(); area = img.FillDomain(x,y,color); for(i=0;i<img_max;i++){ image[i] = img.img[i]; } return area; } void Center_of_Mass(unsigned char* image, int right, int bottom, // image info int x, int y, double* x_cm, double* y_cm) // Domain(x,y) with Center(x_cm, y_cm) { Vector_d2D r_cm; Image img(image, right, bottom); img.Domain(); r_cm = img.CenterofMass(x,y); *x_cm = r_cm.x + 0.5; *y_cm = r_cm.y + 0.5; } double Length_to_the_Edge(unsigned char* image, int right, int bottom, // image info double x0, double y0, double dx, double dy) // Length of Domain from (x0,y0) to the direction (dx,dy) { double l; Image img(image, right, bottom); img.Domain(); l = img.Length_to_Edge(x0, y0, dx, dy); return l; } void Noise_Remove(unsigned char* image, int right, int bottom, // image info int noise_size) { int i, img_max=right*bottom; Image img(image, right, bottom); img.Domain(); img.RemoveNoise(noise_size); for(i=0;i<img_max;i++){ image[i] = img.img[i]; } } ```/
ImgP3.png ImgP3-1.png
A program that shows analyzed distance and time, speed (distance/time), magnetic field values, image brightness, etc.
Since I need to check in various ways to make sure there are no errors (program errors, measurement mistakes, etc.) while analyzing the data, this program was created to view at a glance the various data recorded during the measurement (time, magnetic field values, images).
ImgP4.png ImgP4-1.png
A program that observes the changes in the characteristics of magnetic materials through a microscope and processes the collected photo and video data to measure speed or easily compile and process images to understand characteristics. It selects an image section and projects magnetic field values or time onto the screen to create a video .
Money0.png Money1.png
A wealth analysis program for members of the National Assembly and high-ranking public officials who disclose their assets annually. A simple program that extracts the desired portion from standardized text. It extracts only the text from the "High-ranking Public Officials and Members of the National Assembly Regular Asset Report (2011~2013)" PDF file and transfers it to a txt file (using Ctrl+C, V), analyzes the text pattern, extracts only the name, affiliation, position, and total assets, and plots it as a graph .
TBD.png
Truncated Boson Dynamics Simulation : It is difficult to perfectly solve the problem of bosons (largely classified into bosons and fermions depending on their characteristics) that are too complex and have too many variables. It models and analyzes the state change over time through various simplification processes and approximations. It is a program that calculates numerically using these models and shows the results. Although it is a program that simply implements a few equations, it was a difficult program because there were many things to consider (such as adaptive step size) while programming. Each object (square things, object-oriented programming) was also directly programmed.
ImgP5.png ImgP5-1.png
This program was created to facilitate the movement of photos according to time and magnetic field, as there are many cases where it is necessary to observe changes in the Magnetic Domain according to the magnetic field.
## RRA

    Recoeve.net

  1. https://recoeve.net/, and kipid's blog :: Introducing what we are making : Recoeve.net
  2. github.com/kipid/Recoeve
  3. kipid's blog :: Recoeve Database setup (0.1 version)
  4. kipid's blog :: 개인화 된 추천 시스템 (Personalized recommendation system)
  5. kipid's blog :: 기계 학습 (Machine Learning - Deep Learning)
  6. kipid's blog :: SNS 내보내기/공유하기 (Sharing a URI link through SNS)
  7. kipid's blog :: Delayed (Lazy) Loading in HTML by JavaScript (+jQuery)
  8. kipid's blog :: 공정한 경제란 무엇일까? - 1. 두 명만으로 구성된 사회에서의 경제성장
  9. kipid's google docu :: 개인 소득 공개
  10. As a Programmer and a Physicist.

  11. [IT/Programming]--국비 지원 코딩/공부 of kipid's Recoeve.net:
    https://recoeve.net/user/kipid/mode/multireco?cat=[IT/Programming]--국비 지원 코딩/공부&PRL=0.80&PRR=1.00#numbers-of-recos
  12. kipid's blog :: Conjecture about the Unification between Electro-Magnetic Lorentz force and Gravity
  13. kipid's blog :: Black Holes as Elementary Particles, and Elementary Particles as Mini Black Holes
  14. kipid's blog :: Truncated many-body dynamics of interacting bosons: A variational principle with error monitoring
  15. kipid's blog :: 여러가지 프로그래밍 언어들
  16. kipid's blog :: HTML docuK format ver. 2.0; 개인적으로 만들고 있는 LaTeX 비슷한 형태의 HTML document format.
    // docuK 문서 예제들: kipid's blog :: 텐서(Tensor)와 상대론(Relativity) - 0. 텐서(Tensor)란?, and kipid's blog :: 선형 대수학 간단한 정리들 (Linear Algebra), and kipid's blog :: 최적화, 라그랑지 승수법 (Optimization with the Method of Lagrange multipliers), and kipid's blog :: Method of Lagrange multipliers.
  17. kipid's blog :: LaTeX(라텍스, 레이텍) 소개 및 설명서(Guide)들
  18. kipid's blog :: 반응형 웹 만들기 (Responsible web design with css media query)
  19. kipid's blog :: 인터넷, Web, HTML, 블로그에서 수식 사용하기 (Equation or math in HTML, blog)
  20. Tensor and Relativity - 0. What is Tensor?
  21. kipid's blog :: Interactive graph and chart in HTML
  22. kipid's blog :: 인터넷에서 예쁘게 코드 입력하기 (google code prettify)
  23. kipid's blog :: Improving web performance; Delayed loading 관련.
  24. kipid's blog :: 고위공직자 및 국회의원 정기 재산 신고 사항 (2011~2013) and kipid's blog :: 당신은 상위 몇 % 입니까? (고위직 재산 통계 2013)
  25. kipid's blog :: To correct inaccurate location measured by GPS with Wi-Fi RSSI (Received Signal Strength Indicatior). (Wi-Fi 신호세기를 이용해 GPS 튀는거 잡는 방법.)
  26. Lab Homepage

  27. SNU :: Theory of Cold Atoms.
  28. SNU :: Ultrafast Nanoscopic Spin Dynamics Laboratory (극초고속 나노스핀현상 연구실)
  29. Papers (about Physics only)

  30. Truncated many-body dynamics of interacting bosons: A variational principle with error monitoring, Kang-Soo Lee and Uwe R. Fischer, arXiv:1301.2199 [cond-mat.quant-gas] (2013).
  31. Long-Range Domain Wall Tension in Pt/Co/Pt Films with Perpendicular Magnetic Anisotropy, Kyoung-Woong Moon, Jae-Chul Lee, Soong-Geun Je, Kang-Soo Lee, Kyung-Ho Shin, and Sug-Bong Choe, Appl. Phys. Express 4, 043004 (2011).
  32. Fractal Dimension of Magnetic Domain Walls in CoFe/Pt Multilayers, Kang-Soo Lee, Dong-Hyun Kim, Sug-Bong Choe, J. Magnetics 15(3), 99-102 (2010).
  33. Roughness Exponent of Domain Interface in CoFe/Pt Multilayer Film, Kang-soo Lee, Chang-won Lee, Young-jin Cho, Sunae Seo, Dong-Hyun Kim, Sug-Bong Choe, IEEE Trans. Magn. 45(6), 2548 (2009).
  34. Interdimensional Universality of Dynamic Interfaces, Kab-Jin Kim, Jae-Chul Lee, Sung-Min Ahn, Kang-Soo Lee, Chang-Won Lee, Young Jin Cho, Sunae Seo, Kyung-Ho Shin, Sug-Bong Choe & Hyun-Woo Lee, Nature 458, 740-742 (2009).
  35. Etc.

반응형