1. 程式人生 > 其它 >Medium網友開發了一款應用程式 讓學習演算法和資料結構變得更有趣

Medium網友開發了一款應用程式 讓學習演算法和資料結構變得更有趣

Medium網友Peter Weinberg開發了一款名叫CS-Playground-React的應用程式,可以使大家更有意思、也更加輕鬆地學習演算法和資料結構。

CS-Playground-React介面

  • CS-Playground-React地址:http://cs-playground-react.surge.sh/

Peter Weinberg的自述:我是一名自學成才的程式設計師。我覺得自己做得不夠好,並且在掌握複雜的電腦科學概念方面處於劣勢。

我對數學不是十分擅長。我總是把強大的數學技巧和天生擅長程式設計的能力聯絡在了一起。我覺得我必須比其他人(他們有天生的數學能力)更努力地學習相同的概念。這個想法深深紮根在我的大腦中,我很確定我永遠無法學習像“二叉搜尋樹”這樣的東西,以及如何在精神上分析像“歸併排序”這樣的遞迴噩夢。

所以我想和大家分享一下我的努力是怎樣的,以及我所付出的努力的結果。

進入CS-Playground-React,它是一個瀏覽器內的JavaScript沙盒(sandbox),用於學習和練習演算法和資料結構。這款無需註冊的應用程式可以自動儲存你的進度,當你困住的時候為你提供解決方案,還會提供一些有用的文章、教程和其他資源的連結,讓你的學習過程變得更加輕鬆!

我承認,這款應用並不是什麼開創性的東西。市面上有大量的應用程式,它們教授類似的技能,讓你能夠在瀏覽器中編寫和執行程式碼。

為什麼我做了這個 我開發這款應用的動機很簡單:我想讓學習變得更簡單、更有趣。更重要的是,我為什麼要學習這些特殊技能。在過去的18個月左右,我可以自信地說我已經學會了如何編碼。儘管我仍然不願自稱為程式設計師。通過學習CS的基本原理,我希望不僅能對自己作為一名程式設計師更有信心,而且還能幫助其他人。自學成才的程式設計師是科技行業近年來更容易接受的一種人才。特別是在像矽谷這樣的地方,在每個街角都有程式設計訓練營。然而,對於希望進入這個行業而沒有接受正規電腦科學教育的大多數程式設計師來說,仍然有很多障礙需要克服。

對我來說,學習某些東西的最好方法(尤其是枯燥的東西),就是把它和你喜歡的東西聯絡起來。所以當我在開發這款應用的時候,我也在為它開發內容。現在,學習演算法和資料結構是我的最新專案的一個必要部分。每隔幾天,我就在學習一種新的演算法或資料結構。一旦我把它寫下來,我就會編譯學習資源並把它新增到應用程式中。現在,我可以在一個我自己構建的超級簡單的工作空間中反覆練習。這不是很酷嗎! ?

我發現了一個非常棒的網站,它能讓我們看到如何對演算法和資料結構進行排序。這是快速排序在100個專案陣列中執行的操作。你可以在下面的地址中找到完整的視覺化列表。

  • 地址:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html

技術堆疊和黑客 如果你感興趣的話,我用React & React-Redux(儘管第一個版本是vanilla JS,CSS和HTML)構建了這個應用程式。它還使用了CodeMirror和React-Codemirror2來將一個編輯器嵌入到瀏覽器中(注意:原始版本的React-CodeMirror已經不再被維護,而且在新版本的反應中也沒有很好地發揮作用)。

  • React & React-Redux第一個版本:https://github.com/no-stack-dub-sack/algos-and-data-structures
  • CodeMirror:https://codemirror.net/
  • React-Codemirror2:https://github.com/scniro/react-codemirror2

模擬控制檯 每次使用者在它們的程式碼中呼叫console.log時,一次小的hack就可以觸發一次redux操作。通過這種方式,我可以捕獲已登入的訊息,然後在瀏覽器中模擬一個控制檯以顯示程式碼的輸出。你可以在任何需要清除模擬控制檯訊息的時候執行clearConsole()。

import { store }from './index';

export const hijackConsole= ()=> {
  const OG_LOG= console.log;
    console.log= function(...args) {
    // map over argumentsand convert
    // objectsin to readable strings
    const messages= [...args].map(msg=> {
      return typeof msg !== 'string'
        ? JSON.stringify(msg)
        : msg;
    }).join(' ');
    store.dispatch({
      type: CONSOLE_LOG,
      messages
    });
    // retain original functionality
    OG_LOG.apply(console, [...args]);
  };
};

重新定義console.log捕捉和儲存已記錄的程式碼

持久化程式碼

我想讓這個應用程式超級容易使用。因此,我選擇了一種更簡單的方法來儲存進度,而不是實現資料庫並請求使用者登入。Redux在每個會話期間管理應用程式的狀態,我使用localStorage來在會話中持久化程式碼。該應用程式將在下一次訪問時檢索這個儲存的狀態,並將Redux儲存與它解除凍結。這樣你就可以在你離開的地方找到你的位置。

如果出於某種原因你想要刪除所有的程序,你可以在編輯器中的任何時候執行runresetState()。如果你不想將程式碼提交給本地儲存,那麼在操作之前,不要儲存註釋。這將防止儲存任何程式碼,而不僅僅是為該檔案儲存。

import { store }from './fileWhereStoreLives';

// add this codein your app's entry pointfile to
// set localStorage when navigating awayfrom app
window.onbeforeunload= function(e) {
  const state= store.getState();
  localStorage.setItem(
    'local-storage-key',
    JSON.stringify(state.stateYouWantToPersist)
  );
};
import { importedState }from './fileWhereStateLives';

// define your reducer's initial state:
const initialState= {
  ...importedState;
};

// define default statefor each subsequent visit.
// if localStorage with this key exists, assign it
// to this variable, otherwise, use initialState.
const defaultState= JSON.parse(
  localStorage.getItem('local-storage-key')
) || initialState;

// set defaultState of reducer to result of above operation
const reducer= (state= defaultState, action)=> {
  switch (action.type) {
    case'DO_SOMETHING_COOL':
      return {
        ...state,
        ...action.newState
      };
    default:
      return state;
  }
}

export default reducer;

另一方面,事實證明有一個叫做Redux-Persist的安裝包可以為你做這個。但是對於一個簡單的用例來說,你是否可以用幾行程式碼做一些事情,或者安裝一個NPM包來做同樣的事情? 就我來說,我每次都選擇前者。你很有可能節省了數百行程式碼和一組全新的依賴關係。它總是相互遷就,你必須決定什麼時候高度優化(但更重的)解決方案比簡單的解決方案要好。