Jekyll2019-07-30T14:37:55+08:00https://iamsk.github.io/feed.xmlAM I A GEEKTechnology related, include progaming, hardware, DIY etcBiniamsk.info#gmail.comhttp://iamsk.info2019-07-30T14:37:55+08:002019-07-30T14:37:55+08:00https://iamsk.github.io/2013-02-28-dev-robot-hubot<p>[<strong>Warning </strong>] Please use <code class="highlighter-rouge">Slack</code> instead of <code class="highlighter-rouge">Hubot</code>!</p>
<h1 id="the-structure-of-hubot-and-campfire">the structure of hubot and campfire</h1>
<h2 id="campfire-rooms">campfire rooms:</h2>
<ul>
<li>RoomA
<ul>
<li>RoomB</li>
<li>etc…</li>
</ul>
</li>
</ul>
<h2 id="hubots">hubots</h2>
<ul>
<li>HubotA
<ul>
<li>HubotB</li>
<li>etc…</li>
</ul>
</li>
</ul>
<h2 id="people">People</h2>
<ul>
<li>PeopleA
<ul>
<li>PeopleB</li>
<li>etc…</li>
</ul>
</li>
</ul>
<p>the process of one command:</p>
<p>PeopleN send one command in RoomN, HubotN receive this command, execute and return info.</p>
<p>When one hubot starts, they will monitoring all executable tasks under his folder;</p>
<p>Rooms is based on HUBOT_CAMPFIRE_ACCOUNT, HUBOT_CAMPFIRE_TOKEN and HUBOT_CAMPFIRE_ROOMS</p>
<p>there are two methods for each hubot: respond and hear</p>
<ul>
<li>respond: receive all requests from exactly hubotN;</li>
<li>hear: receive all requests from related rooms.</li>
</ul>
<p>Pros for only one hubot:</p>
<ol>
<li>Easy to manage;</li>
<li>Only need one repo.</li>
</ol>
<p>Cons for only one hubot:</p>
<ol>
<li>Each script have different running env, such as Intranet, Network or VPN, one hubot only can stay in one env;</li>
<li>Some thing like github campfire hook which send cmds without hubot name, then we must use hear or create new hubot and name with the first word.</li>
</ol>
<p>With fine-grained privileges required, we can make each people as unit.</p>
<p>hubot can’t send commands to himself as they use the same campfire token.</p>Biniamsk.info#gmail.comhttp://iamsk.infoThe Evolution of Trust2017-07-31T00:00:00+08:002017-07-31T00:00:00+08:00https://iamsk.github.io/the-evolution-of-trust<p>After play with this game: <a href="http://ncase.me/trust/">http://ncase.me/trust/</a>.</p>
<p>There is a conclusion:</p>
<ol>
<li>REPEAT INTERACTIONS
Trust keeps a relationship going, but you need the knowledge of possible future repeat interactions before trust can evolve.</li>
<li>POSSIBLE WIN-WINS
You must be playing a non-zero-sum game, a game where it’s at least possible that both players can be better off – a win-win.</li>
<li>LOW MISCOMMUNICATION
If the level of miscommunication is too high, trust breaks down. But when there’s a little bit of miscommunication, it pays to be more forgiving.</li>
</ol>
<p>Refs:</p>
<ul>
<li><a href="http://ncase.me/trust/">http://ncase.me/trust/</a></li>
</ul>Biniamsk.info#gmail.comhttp://iamsk.infoAfter play with this game: http://ncase.me/trust/.Thinking about smart home2017-06-15T00:00:00+08:002017-06-15T00:00:00+08:00https://iamsk.github.io/thinking-about-smart-home<p>Currently, in 2017, the <code class="highlighter-rouge">smart home</code> is like mobile phone or pc at 2000, we use DIY computer at that time, but in 2017, we already use brand computer, so smart home should be the same.</p>
<p><code class="highlighter-rouge">Smart home</code>, It’s just like a cement box, we add television, fridge, air-conditioner, mobile phone etc into this box, and make them connected.</p>
<p>We all want smart home, and we make it in our ways, but it’s not good, the whole package is not professional, our tastes is not good as a designer.</p>
<p>Brand with overall solutions, is this a future way for smart home?</p>Biniamsk.info#gmail.comhttp://iamsk.infoCurrently, in 2017, the smart home is like mobile phone or pc at 2000, we use DIY computer at that time, but in 2017, we already use brand computer, so smart home should be the same.Softwares for OSX2017-05-18T07:50:00+08:002017-05-18T07:50:00+08:00https://iamsk.github.io/softwares-for-osx<p>Some softwares used in my Mac :) updated: 2017-05-18</p>
<p>Integrated with https://github.com/iamsk/laptop</p>
<p><code class="highlighter-rouge">B</code> stands for home brew, <code class="highlighter-rouge">C</code> stands for home brew cask, each app sorted with the priority.</p>
<h2 id="base">Base</h2>
<ol>
<li>Homebrew(https://github.com/iamsk/laptop): install CLI apps;</li>
<li>Homebrew Cask(laptop): install GUI apps;</li>
<li>Java(C): java runtime;</li>
<li>GoAgent(<a href="http://t.cn/R5ZobpC">http://t.cn/R5ZobpC</a>): proxy management;</li>
<li>HostsTools(https://github.com/HostsTools/OSX): GFW Hosts</li>
<li>Google Chrome(C);</li>
<li>Ulysses(MAS): markdown editor;</li>
<li>AppCleaner(C): uninstall softwares;</li>
<li>Movist(C)/MplayerX(C): play video;</li>
<li>Netease Music(C): play online music;</li>
<li>iStat Menus(C/L): cpu, mem, network monitoring;</li>
<li>Dropbox(C): cloud storage;</li>
<li>Fliqlo(C): screen protection;</li>
<li>SwitchHosts(C): https://github.com/oldj/SwitchHosts;</li>
<li>Disk Cleaner Suite(MAS): the small set of clean my mac;</li>
<li>TinkerTool(http://www.bresink.com/osx/TinkerTool.html): edit apple hidden settings, configure in cask before;</li>
<li>youtube-dl(B): videos;</li>
<li>you-get(B): videos;</li>
</ol>
<h2 id="communication">Communication</h2>
<ol>
<li>Wechat(MAS): chat with friends, can be replaced with <code class="highlighter-rouge">electronic-wechat</code>(C);</li>
<li>Slack(C): team cooperation chat;</li>
<li>AliWangwang(C): shopping chat;</li>
</ol>
<h2 id="developing">Developing</h2>
<ol>
<li>Xcode(laptop): base programing system;</li>
<li>git(laptop): teamwork coding;</li>
<li>tmux(laptop): manage multiple screens;</li>
<li>zsh(laptop): amazing shell;</li>
<li>oh-my-zsh(https://github.com/robbyrussell/oh-my-zsh): amazing shell extension;</li>
<li>iTerm2(C): extend terminal;</li>
<li>ag(laptop)/ack(B): simple and fast search;</li>
<li>htop(B): process monitor, need sudo;</li>
<li>wget(B): download;</li>
<li>pyenv(B): manage python versions;</li>
<li>ipython(B): wonderful python;</li>
<li>Pycharm(C/L): amazing IDE for Python web developing;</li>
<li>MacVim(C): extend vim;</li>
<li>Sequel Pro(C): mysql client;</li>
<li>Charles(C/L): Network Monitoring for phone;</li>
<li>httpstat(B): network monitoring for curl;</li>
<li>diff-so-fancy(B): good-looking’ diffs;</li>
<li>m-cli(B): Swiss Army Knife for macOS;</li>
<li>Dash(C/L): API documentation browser;</li>
<li>Marmoset(Chrome): code highlight;</li>
<li>Virtualbox(C): install other os system, like ubuntu(dev env) and windows;</li>
<li>Mindnode Pro(C:mindnode-pro): organize things;</li>
<li>Kaleidoscope(C): file compare;</li>
<li>Robomongo(C): mongodb GUI client;</li>
<li>SQLiteManager(C): sqlite GUI client;</li>
<li>adr-tools(B): Command-line tools for working with Architecture Decision Records;</li>
<li>tig(B): interactive git;</li>
<li>axel(B): replace of curl and wget;</li>
<li>fzf(B): replace of find;</li>
<li>Sz/rz(B): replace of scp;</li>
<li>cloc(B): code stats by type;</li>
</ol>
<h2 id="productivity">Productivity</h2>
<ol>
<li>1Password(C/MAS): password management;</li>
<li>Sogou Input Method(C): input method;</li>
<li>Alfred(C/L): used for start up apps;</li>
<li>Powerpack(Alfred): based on Alfred, used for extend workflow;</li>
<li>Spectacle(C): windows manger;</li>
<li>RescueTime(C): log and analyze working time;</li>
<li>Go2Shell(C): directory to iTerm;</li>
<li>QQ(C): capture screen and edit;</li>
<li>CheatSheet(C): query mac commands shortcuts;</li>
<li>MacID(C)/Near Lock: auto lock and unlock screen, replaced by <code class="highlighter-rouge">Touch ID</code>;</li>
<li>Cactus(C): serve static files;</li>
<li>Postman(Chrome): API console;</li>
<li>Google Drive(Chrome): edit and share files;</li>
<li>Text to ASCII Art(Chrome): make some ascii logo;</li>
<li>TeamViewer(C): remote control;</li>
<li>Microsoft Remote Desktop(MAS): login remote windows in Mac;</li>
<li>TextExpander(C): extend system input;</li>
<li>Clean My Mac(C): remove unused files;</li>
<li>Camtasia(C): recording on-screen activity;</li>
<li>Lantern(C): temp use for proxy;</li>
<li>ABBYY FineReader(MAS): ocr tool;</li>
<li>SiteSucker(C): download websites.</li>
</ol>
<h2 id="custom-settings">Custom settings</h2>
<ol>
<li>dotfiles: <a href="https://github.com/thoughtbot/dotfiles">https://github.com/thoughtbot/dotfiles</a>;</li>
<li>oh-my-zsh: <a href="https://github.com/robbyrussell/oh-my-zsh">https://github.com/robbyrussell/oh-my-zsh</a>;</li>
<li>Update ~/~.gitignore for global;</li>
<li>Sync typos: <a href="http://iamsk.info/sync-typos-between-two-macs/">http://iamsk.info/sync-typos-between-two-macs/</a>;</li>
<li>Pycharm theme: <a href="https://github.com/jkaving/intellij-colors-solarized">https://github.com/jkaving/intellij-colors-solarized</a>;</li>
<li>dot-vimrc: <a href="https://github.com/humiaozuzu/dot-vimrc">https://github.com/humiaozuzu/dot-vimrc</a>.</li>
</ol>Biniamsk.info#gmail.comhttp://iamsk.infoSome softwares used in my Mac :) updated: 2017-05-18feed stream build tips2017-02-28T00:00:00+08:002017-02-28T00:00:00+08:00https://iamsk.github.io/feed-stream-build-tips<p>The brief design is</p>
<ul>
<li>Actor. The object that performed the activity.</li>
<li>Verb. The verb phrase that identifies the action of the activity.</li>
<li>Action Object. (Optional) The object linked to the action itself.</li>
<li>Target. (Optional) The object to which the activity was performed.</li>
</ul>
<p>For example: justquick (actor) closed (verb) issue 2 (object) on django-activity-stream(target) 12 hours ago</p>
<p>For user friendly,</p>
<ol>
<li>we can combine the actors into one line to make the feeds less;</li>
<li>we can use redis to generate feeds per user (feed:user_id);</li>
<li>split online users and offline users, push the online users first.</li>
</ol>
<p>We can build this with good design frameworks: <a href="http://django-activity-stream.readthedocs.io/en/latest/">Django Activity Stream </a> and <a href="http://getstream.io/">getstream</a>.</p>Biniamsk.info#gmail.comhttp://iamsk.infoThe brief design iswhat is pre commit looks like and how to implement it2017-01-11T00:00:00+08:002017-01-11T00:00:00+08:00https://iamsk.github.io/what-is-pre-pommit-looks-like-and-how-to-implement-it<p>The <code class="highlighter-rouge">pre-commit</code> can find and fix common issues before changes are submitted for code review;</p>
<p>Code reviewers should pay attention to the architecture of a change and not worry about trivial errors like <code class="highlighter-rouge">syntax error</code>, <code class="highlighter-rouge">not following code style</code>, <code class="highlighter-rouge">test missing</code>.</p>
<h2 id="how-to-implement-pre-commit-tldr">How to implement pre-commit [TL;DR]</h2>
<ol>
<li>write a python script(<code class="highlighter-rouge">pre-commit.py</code>) to check all the checkable files and print error messages;
<ol>
<li>get all committed files;</li>
<li>filter with exclude files;</li>
<li>split files into <code class="highlighter-rouge">.py</code>, <code class="highlighter-rouge">.js</code> and <code class="highlighter-rouge">.html</code>;</li>
<li>check with customize pep8, pylint, isort, jshint, jscs etc;</li>
<li>commit continue if all check pass, else we will have more details in report file.</li>
</ol>
</li>
<li>write a shell script(<code class="highlighter-rouge">pre_commit</code>)(name should not change) which actually called by git command;
<ol>
<li>active the specific env(which create by step 3);</li>
<li>execute the real checker script.</li>
</ol>
</li>
<li>write another shell script(<code class="highlighter-rouge">install_pre_commit.sh</code>) to install pre-commit;
<ol>
<li>make a independent env with virtualenv;</li>
<li>install third libs in this env, such as pep8, pylint, isort etc(make sure they have specific version number);</li>
<li>copy the <code class="highlighter-rouge">pre_commit</code> shell script to git directory and make it executable.</li>
</ol>
</li>
</ol>
<h2 id="actually-you-should-not-reinvent-the-wheel">Actually you should not reinvent the wheel</h2>
<ol>
<li>pip install pre-commit;</li>
<li>pre-commit install;</li>
<li>create file <code class="highlighter-rouge">.pre-commit-hooks.yaml</code> at the root of your repo and configure your hooks.</li>
</ol>
<h3 id="the-simplest-hooks-configuration-like-this">the simplest hooks configuration like this:</h3>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">-</span> <span class="n">repo</span><span class="p">:</span> <span class="n">git</span><span class="p">:</span><span class="o">//</span><span class="n">github</span><span class="o">.</span><span class="n">com</span><span class="o">/</span><span class="n">pre</span><span class="o">-</span><span class="n">commit</span><span class="o">/</span><span class="n">pre</span><span class="o">-</span><span class="n">commit</span><span class="o">-</span><span class="n">hooks</span>
<span class="n">sha</span><span class="p">:</span> <span class="n">v0</span><span class="o">.</span><span class="mf">4.2</span>
<span class="n">hooks</span><span class="p">:</span>
<span class="o">-</span> <span class="nb">id</span><span class="p">:</span> <span class="n">trailing</span><span class="o">-</span><span class="n">whitespace</span>
</code></pre></div></div>
<h3 id="additional-information">additional information</h3>
<ul>
<li><a href="http://pre-commit.com/hooks.html">Out of box hooks</a></li>
<li><a href="http://pre-commit.com/#new-hooks">How to create custom hooks</a></li>
<li><a href="http://pre-commit.com/#install">Tutorial</a></li>
</ul>Biniamsk.info#gmail.comhttp://iamsk.infoThe pre-commit can find and fix common issues before changes are submitted for code review;Kudo Box2017-01-05T00:00:00+08:002017-01-05T00:00:00+08:00https://iamsk.github.io/kudobox<blockquote>
<p>Anything that has real and lasting value is always a gift from within.
— Franz Kafka</p>
</blockquote>
<p>A gift from within is an intrinsic motivation, which is more valuable and lasting longer than extrinsic motivation.</p>
<p>People has the need to be recognized by your peers. Kudobox is a tool facilitating this.</p>
<h2 id="steps">Steps</h2>
<p>As we have four teams around the world, I will show you an online way:</p>
<ul>
<li>When anybody in the company feels your peer deserve a recognition, like, he fixed your dev environment, share some knowledge to you, teach you some new skills, etc. You can send she/he one kudo card;</li>
<li>Visit <a href="http://kudobox.co/">http://kudobox.co/</a>, choose a card and write done the specific reason on it;</li>
<li>Share the card into your chat group and mention the receiver, like slack, so team members can react on this;</li>
<li>At weekly meeting, there will be someone to take out all kudo cards and announce it publicly;</li>
<li>Optional, Send some little presents to the top winners.</li>
</ul>
<p>Demo: http://kudobox.co/kudos/0SNrUvaYfwaoxfNLfKbu91w.png</p>
<p><img src="/photos/kudocard.png" alt="Kudo Card" /></p>
<h2 id="rules">Rules</h2>
<ol>
<li>Don’t promise rewards in advance.</li>
<li>Keep anticipated rewards small.</li>
<li>Reward continuously, not once.</li>
<li>Reward publicly, not privately.</li>
<li>Reward behavior, not outcome.</li>
<li>Reward peers, not subordinates.</li>
</ol>
<p>More details in <a href="https://management30.com/practice/kudo-box/">https://management30.com/practice/kudo-box/</a></p>Biniamsk.info#gmail.comhttp://iamsk.infoAnything that has real and lasting value is always a gift from within. — Franz KafkaCacheback - asynchronous cache2017-01-02T00:00:00+08:002017-01-02T00:00:00+08:00https://iamsk.github.io/cache<blockquote>
<p>The fastest code is, of course, code that never runs.
— Jacob Kaplan-Moss</p>
</blockquote>
<h2 id="django-cacheback">django-cacheback</h2>
<p>For a long time, I want to write something about cache until I find django-cacheback. The main difference between cacheback and other design is <code class="highlighter-rouge">asynchronously</code>. Other synchronous design of cache already talked a lot on the internet. Why I choose cacheback? because it can fix the <code class="highlighter-rouge">cash crash</code> issue without sharding.</p>
<p>It’s a smart caching and the key idea being that it’s better to serve a stale item (and populate the cache asynchronously) than block the response process in order to populate the cache synchronously.</p>
<h3 id="demo">demo</h3>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">requests</span>
<span class="kn">from</span> <span class="nn">cacheback.decorators</span> <span class="kn">import</span> <span class="n">cacheback</span>
<span class="nd">@cacheback</span><span class="p">(</span><span class="n">fetch_on_miss</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">fetch_tweets</span><span class="p">(</span><span class="n">username</span><span class="p">):</span>
<span class="n">url</span> <span class="o">=</span> <span class="s">"https://twitter.com/statuses/user_timeline.json?screen_name=</span><span class="si">%</span><span class="s">s"</span>
<span class="k">return</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span> <span class="o">%</span> <span class="n">username</span><span class="p">)</span><span class="o">.</span><span class="n">json</span>
</code></pre></div></div>
<ul>
<li>Cache items for 10 minutes.</li>
<li>For a cache miss, None will be returned and the cache refreshed asynchronously.</li>
</ul>
<p>Read article <a href="http://codeinthehole.com/writing/cacheback-asynchronous-cache-refreshing-for-django/">Cacheback - asynchronous cache refreshing for Django</a> first, you will find the difference between them.
BTW, I find this lib as the author write a famous e-commerce framework <a href="https://github.com/django-oscar/django-oscar">django-oscar</a></p>
<h2 id="what-are-we-caring-about-when-designing-cache">what are we caring about when designing cache?</h2>
<ul>
<li>Cache name: feature related</li>
<li>Key structure: generated automatically with unique name, meaningful and easy to do batch operation</li>
<li>Value structure: performance related (json, pickle, etc)</li>
<li>When this cache has been generated?</li>
<li>When this cache will be flushed?</li>
<li>When this cache will be fetched?</li>
<li>What if cache crash?</li>
</ul>
<h2 id="a-usable-design">A usable design</h2>
<p><a href="https://github.com/iamsk/cacher">https://github.com/iamsk/cacher</a></p>
<h2 id="refs">Refs:</h2>
<p><a href="http://conferences.oreilly.com/oscon/oscon2012/public/schedule/detail/24030">Django doesn’t scale! (And what you can do about it.)</a>
<a href="http://django-cacheback.readthedocs.io/en/latest/index.html">django-cacheback docs</a>
<a href="https://www.fullstackpython.com/caching.html">https://www.fullstackpython.com/caching.html</a></p>Biniamsk.info#gmail.comhttp://iamsk.infoThe fastest code is, of course, code that never runs. — Jacob Kaplan-Moss重构 django settings2016-12-30T00:00:00+08:002016-12-30T00:00:00+08:00https://iamsk.github.io/refactoring-django-settings<p>使用 Django 的团队,总会面临 settings.py 配置文件臃肿的问题,并且随着第三方引用涉及的配置增多及多项目存在冗余配置时,这个问题更加突出了</p>
<h3 id="我们现有的场景">我们现有的场景</h3>
<ol>
<li>
<p>多数情况下,各个项目的配置文件应该独立,但是对于一个公司内部,往往各个项目配置存在一致的情况,所以我们此处要求配置可以跨项目共用</p>
<p>我们有多个项目(WEB, API, AGENCY, ERP, etc),可共用配置涉及:</p>
<ul>
<li>Environment</li>
<li>Storage (DB, Cache, etc)</li>
<li>USE_I18N, admin theme, geoip</li>
<li>etc…</li>
</ul>
</li>
<li>单个项目有多种不同的环境(Production, Staging, Test, CI, Dev, etc);</li>
<li>单配置文件过于复杂,包括 Django 自带的配置,项目配置,第三方库的配置(CMS, celery, payment, swagger, ckeditor, sms, email, geoip, etc),目前已突破 1300 行。</li>
</ol>
<h3 id="基于以上问题我认为-settings-应该被重组并至少分为以下四类">基于以上问题,我认为 settings 应该被重组并至少分为以下四类</h3>
<ol>
<li>公共配置</li>
<li>项目配置</li>
<li>第三方应用配置</li>
<li>环境配置</li>
</ol>
<h3 id="方案一旧方式曾使用">方案一(旧方式,曾使用)</h3>
<ul>
<li>项目之间通过拷贝+更新的方式;</li>
<li>环境之间通过引入 local_settings.py 这种古老的方式;</li>
</ul>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">try</span><span class="p">:</span>
<span class="kn">from</span> <span class="nn">local_settings</span> <span class="kn">import</span> <span class="o">*</span>
<span class="k">except</span> <span class="nb">ImportError</span><span class="p">:</span>
<span class="k">pass</span>
</code></pre></div></div>
<ul>
<li>拆出第三方配置,改为引入,类似 local_settings 这种;</li>
</ul>
<h4 id="优点">优点:</h4>
<ul>
<li>Django 原生方式,无需大的改动,即可满足需要</li>
</ul>
<h4 id="缺点">缺点:</h4>
<ul>
<li>文件级别方案无法保证更细粒度的重用,如 <code class="highlighter-rouge">INSTALLED_APPS</code>, <code class="highlighter-rouge">DATABASES</code>, etc;</li>
<li>方案不优雅,配置间依赖关系全靠导入顺序决定,不直观,新引入的配置容易破坏原配置规范;</li>
<li>配置定位不方便。</li>
</ul>
<h3 id="方案二新方式使用中">方案二(新方式,使用中)</h3>
<p>django-configurations: <a href="https://django-configurations.readthedocs.io/en/stable/">https://django-configurations.readthedocs.io/en/stable/</a></p>
<ol>
<li>Server specific settings: 解决环境差异;</li>
<li>Global settings defaults: 解决公用配置问题;</li>
<li>Configuration mixins: 解决第三方配置的复用。</li>
</ol>
<h4 id="优点-1">优点:</h4>
<ul>
<li>借助类的面向对象,可以实现各种粒度的组合与重用。</li>
</ul>
<h4 id="缺点-1">缺点:</h4>
<ul>
<li>与 Django 原生 settings 不同,此配置基于类的形式。</li>
</ul>Biniamsk.info#gmail.comhttp://iamsk.info使用 Django 的团队,总会面临 settings.py 配置文件臃肿的问题,并且随着第三方引用涉及的配置增多及多项目存在冗余配置时,这个问题更加突出了Sync typos between two Macs2016-12-09T00:00:00+08:002016-12-09T00:00:00+08:00https://iamsk.github.io/sync-typos-between-two-macs<p>I think every programer or writer may face this scenario, when we write some text in mac, the OS may detect typo for us.
So we need train the OS to learn those new words which OS treat them as typo.</p>
<p><img src="/photos/learn-middle.png" alt="Learn-spelling" /></p>
<h2 id="some-typo-dictionaries-for-programer">some typo dictionaries for programer</h2>
<ul>
<li>Mac
~/Library/Spelling/LocalDictionary</li>
<li>PyCharm
.idea/dictionaries/{username}.xml</li>
</ul>
<h2 id="build-unique-localdictionary">build unique LocalDictionary</h2>
<blockquote>
<p>The words in the dictionary file are arranged alphabetically. When your Mac scans to see if the dictionary contains a word, it stops once it reaches the point where it should be. In other words, if you put the word colour at the end of the dictionary, it will not be detected because spell check will only look up to theCs.
Similarly, if you put the word Zebedee at the start of your list, spell check would stop instantly. When you are adding words to the dictionary you must be careful to keep them in alphabetical order.
— <a href="https://github.com/PhilETaylor">PhilETaylor</a></p>
</blockquote>
<p>Fixed with Mac level should be more generic, so read article <a href="https://computers.tutsplus.com/tutorials/quick-tip-bulk-add-words-to-your-macs-spell-check-dictionary--mac-60820">Quick Tip: Bulk Add Words to Your Mac’s Spell Check Dictionary</a> to build your unique <code class="highlighter-rouge">LocalDictionary</code>.</p>
<h2 id="use-a-soft-link-to-dropbox-will-be-fine">Use a soft link to dropbox will be fine.</h2>
<p><strong>Link the directory <code class="highlighter-rouge">Spelling</code> instead of the file <code class="highlighter-rouge">LocalDictionary</code></strong> as when you learn a new word, the symbol file will change to an ordinary file, the link will broken.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cp -r ~/Library/Spelling ~/Dropbox
cd ~/Library
rm -rf Spelling
ln -s ~/Dropbox/Spelling
</code></pre></div></div>
<p>Restart spell check by running <code class="highlighter-rouge">killall AppleSpell</code>, it’s better add this in your cronjob as the synced words need update the Apple cache.</p>
<h2 id="refs">refs</h2>
<ul>
<li><a href="http://www.techradar.com/how-to/software/applications/how-to-improve-the-os-x-dictionary-1297396">How to improve the Mac OS X Dictionary</a></li>
<li><a href="https://github.com/bchroneos/system-tweaks">MacSpelling shell</a></li>
<li><a href="https://gist.github.com/PhilETaylor/9e7fd5ba5ffc52fa8dec">https://gist.github.com/PhilETaylor/9e7fd5ba5ffc52fa8dec</a></li>
</ul>Biniamsk.info#gmail.comhttp://iamsk.infoI think every programer or writer may face this scenario, when we write some text in mac, the OS may detect typo for us. So we need train the OS to learn those new words which OS treat them as typo.