<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Tools on When Moore's Law Ends</title><link>https://jimwang99.github.io/posts/tools/</link><description>Recent content in Tools on When Moore's Law Ends</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Mon, 15 Jun 2020 00:00:00 +0000</lastBuildDate><atom:link href="https://jimwang99.github.io/posts/tools/index.xml" rel="self" type="application/rss+xml"/><item><title>Status of current HDL generator</title><link>https://jimwang99.github.io/posts/tools/status-of-current-hdl-generator/</link><pubDate>Mon, 15 Jun 2020 00:00:00 +0000</pubDate><guid>https://jimwang99.github.io/posts/tools/status-of-current-hdl-generator/</guid><description>&lt;p>Recently, I’m trying out different HDL generator languages and tools, because&lt;/p>
&lt;ol>
&lt;li>Chisel is used heavily inside SiFive, and they have developed amount of IPs including very complicated CPUs, and a very well maintained community (mainly students from Berkeley)&lt;/li>
&lt;li>Many other IP companies are using their type of HDL generator to generate RTL
&lt;ol>
&lt;li>Such as ARM and Cadence. ARM’s CPU is delivered as a very well parameterized Verilog file along with a set of scripts that can take your configuration file can generate RTL/testbench/IPXACT/… accordingly in less than a minute.&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>HDL generator is pushed inside our team in FB, and believed to be the future of hardware design because of boost of productivity&lt;/li>
&lt;/ol>
&lt;p>The productivity boost of generator is coming from&lt;/p></description></item><item><title>shortcut.py A Command Line Script to Provide Macro</title><link>https://jimwang99.github.io/posts/tools/shortcut-py-a-command-line-script-to-provide-macro/</link><pubDate>Mon, 11 Feb 2019 00:00:00 +0000</pubDate><guid>https://jimwang99.github.io/posts/tools/shortcut-py-a-command-line-script-to-provide-macro/</guid><description>&lt;h2 id="typical-usage">Typical usage&lt;a class="anchor" href="#typical-usage">#&lt;/a>&lt;/h2>
&lt;h3 id="go-to-some-directory-use-short-alias">&lt;code>go&lt;/code> to some directory use short alias&lt;a class="anchor" href="#go-to-some-directory-use-short-alias">#&lt;/a>&lt;/h3>
&lt;pre tabindex="0">&lt;code>&amp;gt; pwd
/home/jw
&amp;gt; go prj0
cd /work/projects/design/master-branch/
&amp;gt; pwd
/work/projects/design/master-branch/&lt;/code>&lt;/pre>&lt;h3 id="run-a-serial-of-commands-use-short-alias">&lt;code>run&lt;/code> a serial of commands use short alias&lt;a class="anchor" href="#run-a-serial-of-commands-use-short-alias">#&lt;/a>&lt;/h3>
&lt;pre tabindex="0">&lt;code>&amp;gt; run vnc
ssh -L 5901:remote-internal-server-name:5901 jw@remote-gateway-ip
vncviewer remote-internal-server-name&lt;/code>&lt;/pre>&lt;h3 id="search-available-alias">Search available alias&lt;a class="anchor" href="#search-available-alias">#&lt;/a>&lt;/h3>
&lt;p>Here &lt;code>.&lt;/code> dot is used to replace &lt;code>*&lt;/code> star because &lt;code>zsh&lt;/code> will try to expand &lt;code>*&lt;/code> by default.&lt;/p>
&lt;pre tabindex="0">&lt;code>&amp;gt; go
prj0
&amp;gt; go p.
prj0
&amp;gt; run
vnc&lt;/code>&lt;/pre>&lt;h3 id="auto-correction">Auto-correction&lt;a class="anchor" href="#auto-correction">#&lt;/a>&lt;/h3>
&lt;p>&lt;code>shortcut.py&lt;/code> uses &lt;code>difflib.get_close_matches&lt;/code> to auto-correct the alias.&lt;/p></description></item><item><title>Static Site Generator</title><link>https://jimwang99.github.io/posts/tools/static-site-generator/</link><pubDate>Sat, 19 Jan 2019 00:00:00 +0000</pubDate><guid>https://jimwang99.github.io/posts/tools/static-site-generator/</guid><description>&lt;p>Trying to find the perfect static site generator. Used to use Pelican, because it’s written in Python. Also tried with Jekyll, the most popular candidate, because it’s used by Github. Their common problems are&lt;/p>
&lt;ul>
&lt;li>Not intuitive enough. Seems like something programmer created for programmer.&lt;/li>
&lt;li>There are very restricted requirements of directory structure of the content. And they doesn’t fit my understanding/requirement.&lt;/li>
&lt;/ul>
&lt;p>Now I’m trying Hugo, which is written in Go, and it’s really fast. The best feature I like about it is &lt;strong>page bundles&lt;/strong>. It allows you to put articles in the same/separated directory with their own resources.&lt;/p></description></item><item><title>GCP (Google Cloud Platform)</title><link>https://jimwang99.github.io/posts/tools/gcp-google-cloud-platform/</link><pubDate>Sun, 21 Oct 2018 00:00:00 +0000</pubDate><guid>https://jimwang99.github.io/posts/tools/gcp-google-cloud-platform/</guid><description>&lt;h2 id="price-of-gcp">Price of GCP&lt;a class="anchor" href="#price-of-gcp">#&lt;/a>&lt;/h2>
&lt;h3 id="persistance-disk">Persistance Disk&lt;a class="anchor" href="#persistance-disk">#&lt;/a>&lt;/h3>
&lt;p>Can be used to put all the data/eda/os on it.&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>Price (per month)&lt;/th>
 &lt;th>Price (per GB per month)&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>SSD 50GB&lt;/td>
 &lt;td>$8.50&lt;/td>
 &lt;td>$0.17&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>SSD 1TB&lt;/td>
 &lt;td>$174.08&lt;/td>
 &lt;td>$0.17&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>HDD 50GB&lt;/td>
 &lt;td>$2.00&lt;/td>
 &lt;td>$0.04&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>HDD 200GB&lt;/td>
 &lt;td>$8.00&lt;/td>
 &lt;td>$0.04&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>HDD 1TB&lt;/td>
 &lt;td>$39.76&lt;/td>
 &lt;td>$0.04&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Snapshot 50GB&lt;/td>
 &lt;td>$1.30&lt;/td>
 &lt;td>$0.026&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="always-on-instance-24x7">Always on instance (24x7)&lt;a class="anchor" href="#always-on-instance-24x7">#&lt;/a>&lt;/h3>
&lt;p>Can be used as working machine (support VNC) and NFS server&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>vCPU&lt;/th>
 &lt;th>RAM (GB)&lt;/th>
 &lt;th>Price (per month)&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>f1-micro&lt;/td>
 &lt;td>Shared&lt;/td>
 &lt;td>0.60&lt;/td>
 &lt;td>Free&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>g1-small&lt;/td>
 &lt;td>Shared&lt;/td>
 &lt;td>1.70&lt;/td>
 &lt;td>$13.80&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>n1-std-1&lt;/strong>&lt;/td>
 &lt;td>1&lt;/td>
 &lt;td>3.75&lt;/td>
 &lt;td>$24.27&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>n1-std-2&lt;/td>
 &lt;td>2&lt;/td>
 &lt;td>7.50&lt;/td>
 &lt;td>$48.55&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="instance-for-eda-10-hours-per-week-43452-hours-per-month">Instance for EDA (10 hours per week, 43.452 hours per month)&lt;a class="anchor" href="#instance-for-eda-10-hours-per-week-43452-hours-per-month">#&lt;/a>&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>&lt;/th>
 &lt;th>vCPU&lt;/th>
 &lt;th>RAM (GB)&lt;/th>
 &lt;th>Price (per month)&lt;/th>
 &lt;th>Price (per hour)&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>n1-cpu-8&lt;/td>
 &lt;td>8&lt;/td>
 &lt;td>7.2&lt;/td>
 &lt;td>$12.32&lt;/td>
 &lt;td>$0.2835&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>n1-std-8&lt;/td>
 &lt;td>8&lt;/td>
 &lt;td>30&lt;/td>
 &lt;td>$16.51&lt;/td>
 &lt;td>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>n1-mem-8&lt;/td>
 &lt;td>8&lt;/td>
 &lt;td>52&lt;/td>
 &lt;td>$20.58&lt;/td>
 &lt;td>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>n1-cpu-16&lt;/td>
 &lt;td>16&lt;/td>
 &lt;td>14.4&lt;/td>
 &lt;td>$24.65&lt;/td>
 &lt;td>$0.5673&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>n1-std-16&lt;/td>
 &lt;td>16&lt;/td>
 &lt;td>60&lt;/td>
 &lt;td>$33.02&lt;/td>
 &lt;td>$0.7599&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>n1-cpu-32&lt;/td>
 &lt;td>32&lt;/td>
 &lt;td>28.8&lt;/td>
 &lt;td>$49.29&lt;/td>
 &lt;td>$1.1344&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>At the meantime, secondhand server on unixsurplus is “E5-2620 V3 10-CORE 2.4GHz” with “64GB DDR4” and “300GB HDD” is $1,989. It’s n1-std-16 for 2617 hours, 261.7 weeks if 10 hours per week.&lt;/p></description></item><item><title>Docker for EDA</title><link>https://jimwang99.github.io/posts/tools/docker-for-eda/</link><pubDate>Mon, 01 Oct 2018 00:00:00 +0000</pubDate><guid>https://jimwang99.github.io/posts/tools/docker-for-eda/</guid><description>&lt;h2 id="dockerfile">Dockerfile&lt;a class="anchor" href="#dockerfile">#&lt;/a>&lt;/h2>
&lt;pre tabindex="0">&lt;code>FROM ubuntu:16.04
COPY ./boot.sh /tmp
COPY ./hello.sh /tmp
RUN /bin/bash /tmp/boot.sh
RUN /bin/bash /tmp/hello.sh&lt;/code>&lt;/pre>&lt;h2 id="bootsh">boot.sh&lt;a class="anchor" href="#bootsh">#&lt;/a>&lt;/h2>
&lt;pre tabindex="0">&lt;code>apt-get update; apt-get install -y make autoconf g++ flex bison wget
cd /tmp
wget https://www.veripool.org/ftp/verilator-4.004.tgz
tar xf verilator*.tgz
cd verilator*
./configure
make # this step will take sometime
make install&lt;/code>&lt;/pre>&lt;h2 id="hellosh">hello.sh&lt;a class="anchor" href="#hellosh">#&lt;/a>&lt;/h2>
&lt;pre tabindex="0">&lt;code>cd /tmp/verilator*
cd ./example/tracing_c
make

# it will print out some log, and after finish it will generate a directory in the same directory named &amp;#34;logs&amp;#34; who needs to be saved after container exit&lt;/code>&lt;/pre>&lt;h2 id="docker-how-to-notes">Docker how-to notes&lt;a class="anchor" href="#docker-how-to-notes">#&lt;/a>&lt;/h2>
&lt;h3 id="create-a-docker-image-from-dockerfile">create a docker image from Dockerfile&lt;a class="anchor" href="#create-a-docker-image-from-dockerfile">#&lt;/a>&lt;/h3>
&lt;pre tabindex="0">&lt;code>docker build -t &amp;#34;$(name):$(tag)&amp;#34; .; # in a directory with Dockerfile

docker run -dit --name $(name) $(name):$(tag); # -d: detach, -i: interactive, -t: tty

docker ps; # use -a to list exited docker; use &amp;#34;docker rm&amp;#34; to remove useless containers

docker exec -it $(name) /bin/bash; # run bash in guest and connect to it

docker commit -m &amp;#34;install/test verilator-4.004&amp;#34; -a &amp;#34;jw&amp;#34; $(name) $(new_name):$(new_tag); # -m: message, -a: author, with new name and tag

docker image ls; # and the image is 797MB large comparing to eda:0.0&amp;#39;s 116MB; use &amp;#34;docker image rm&amp;#34; to remove useless docker images&lt;/code>&lt;/pre>&lt;h3 id="save-file-to-host">save file to host&lt;a class="anchor" href="#save-file-to-host">#&lt;/a>&lt;/h3>
&lt;pre tabindex="0">&lt;code># mount a host dir to guest /mnt/result
DATE=`date &amp;#39;+%Y%m%d_%H%M%S&amp;#39;`
mkdir result_${DATE}
docker run -it -v ${PWD}/result_${DATE}:/mnt/result eda:0.1 /bin/bash

# in guest, copy files to /mnt/result afterwards
# but the files in result_${DATE} will have permission of root:root
# the easiest way to fix the problem is in host do:
sudo chown -R $(id -u) ./result_${DATE}
sudo chown -R $(id -g) ./result_${DATE}&lt;/code>&lt;/pre>&lt;h3 id="stop">stop&lt;a class="anchor" href="#stop">#&lt;/a>&lt;/h3>
&lt;pre tabindex="0">&lt;code>docker stop $(name)&lt;/code>&lt;/pre></description></item><item><title>Course Note of Python Design Patterns</title><link>https://jimwang99.github.io/posts/tools/course-note-of-python-design-patterns/</link><pubDate>Wed, 17 May 2017 00:00:00 +0000</pubDate><guid>https://jimwang99.github.io/posts/tools/course-note-of-python-design-patterns/</guid><description>&lt;blockquote class='book-hint '>
&lt;p>The course is on Coursera&lt;/p>&lt;/blockquote>&lt;h2 id="understanding-design-patterns">understanding design patterns&lt;a class="anchor" href="#understanding-design-patterns">#&lt;/a>&lt;/h2>
&lt;ul>
&lt;li>what?
&lt;ul>
&lt;li>well-known solutions for recurring problems&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>why?
&lt;ul>
&lt;li>don&amp;rsquo;t reinvent wheels&lt;/li>
&lt;li>reuse best practices&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>characteristics
&lt;ul>
&lt;li>language neutral&lt;/li>
&lt;li>dynamic&lt;/li>
&lt;li>incomplete by design to promote customization&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>types
&lt;ul>
&lt;li>creational&lt;/li>
&lt;li>structual&lt;/li>
&lt;li>behavioral&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>OOP (object-oriented programming)
&lt;ul>
&lt;li>design pattern relies on OOP&lt;/li>
&lt;li>attributes + methods&lt;/li>
&lt;li>inheritence &amp;amp; polymorphism&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>pattern context
&lt;ul>
&lt;li>participants and their rols&lt;/li>
&lt;li>quality attributes: nonfunctional requirements&lt;/li>
&lt;li>forces: various factors or trade-offs to consider&lt;/li>
&lt;li>consequences: side effects by decision makers&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>pattern language
&lt;ul>
&lt;li>name&lt;/li>
&lt;li>context&lt;/li>
&lt;li>problem&lt;/li>
&lt;li>solution&lt;/li>
&lt;li>related patterns&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h2 id="creational-patterns">creational patterns&lt;a class="anchor" href="#creational-patterns">#&lt;/a>&lt;/h2>
&lt;h3 id="factory">factory&lt;a class="anchor" href="#factory">#&lt;/a>&lt;/h3>
&lt;ul>
&lt;li>create and return object on the fly
&lt;ul>
&lt;li>flexibility of adding new classes&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>problem
&lt;ul>
&lt;li>uncertainties in types of objects&lt;/li>
&lt;li>runtime decision of types of objects&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="abstract-facotry">abstract facotry&lt;a class="anchor" href="#abstract-facotry">#&lt;/a>&lt;/h3>
&lt;ul>
&lt;li>a factory dynamically uses different factories to create objects on the fly&lt;/li>
&lt;li>problem
&lt;ul>
&lt;li>create a family of related objects at runtime&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>concepts
&lt;ul>
&lt;li>abstract factory&lt;/li>
&lt;li>concrete factory (the real factory used at runtime)&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="singleton">singleton&lt;a class="anchor" href="#singleton">#&lt;/a>&lt;/h3>
&lt;ul>
&lt;li>only one object from a class&lt;/li>
&lt;li>problem
&lt;ul>
&lt;li>cache information shared by multiple objects&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul></description></item><item><title>Scala First Look</title><link>https://jimwang99.github.io/posts/tools/scala-first-look/</link><pubDate>Sun, 14 May 2017 00:00:00 +0000</pubDate><guid>https://jimwang99.github.io/posts/tools/scala-first-look/</guid><description>&lt;blockquote class='book-hint '>
&lt;p>Scala introduction course on LinkedIn. Not very useful, if not using it in real project.&lt;/p>&lt;/blockquote>&lt;h2 id="introduction">introduction&lt;a class="anchor" href="#introduction">#&lt;/a>&lt;/h2>
&lt;ul>
&lt;li>short for Scalable language&lt;/li>
&lt;li>object-oriented + functional programming
&lt;ul>
&lt;li>everything is object
&lt;ul>
&lt;li>including numbers and functions&lt;/li>
&lt;li>does not include primitive data types&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>can pass/assign function: functional programming&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>seamless compatible with Java
&lt;ul>
&lt;li>runs on JVM, compile to JVM&lt;/li>
&lt;li>reuse Java libraries and types&lt;/li>
&lt;li>can call any Java code&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>REPL interactive shell
&lt;ul>
&lt;li>read, eval, print, loop&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h2 id="syntax">syntax&lt;a class="anchor" href="#syntax">#&lt;/a>&lt;/h2>
&lt;ul>
&lt;li>define: &lt;code>var&lt;/code> (variable) vs &lt;code>val&lt;/code> (value)
&lt;ul>
&lt;li>&lt;code>var&lt;/code> defines variables that can be changed
&lt;ul>
&lt;li>but cannot change from one data type to another, ex. from Int to Double&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;code>val&lt;/code> defines variables that cannot be changed (immutable)
&lt;ul>
&lt;li>such as string, char&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>TIPS: worksheet
&lt;ul>
&lt;li>while save, output result of every line of code to source file as comment&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>underscore &lt;code>_&lt;/code> is a special char in Scala, so it cannot be used in variable name&lt;/li>
&lt;/ul>
&lt;h3 id="data-type">data type&lt;a class="anchor" href="#data-type">#&lt;/a>&lt;/h3>
&lt;ul>
&lt;li>Any
&lt;ul>
&lt;li>AnyVal
&lt;ul>
&lt;li>Int&lt;/li>
&lt;li>Double&lt;/li>
&lt;li>Boolean&lt;/li>
&lt;li>…&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>AnyRef
&lt;ul>
&lt;li>String&lt;/li>
&lt;li>Vector&lt;/li>
&lt;li>Array&lt;/li>
&lt;li>…&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>Null&lt;/li>
&lt;li>Nothing&lt;/li>
&lt;/ul>
&lt;h3 id="repetition-statements">repetition statements&lt;a class="anchor" href="#repetition-statements">#&lt;/a>&lt;/h3>
&lt;ul>
&lt;li>&lt;code>while&lt;/code>&lt;/li>
&lt;li>&lt;code>for&lt;/code>
&lt;ul>
&lt;li>iterate a list: &lt;code>for (f &amp;lt;- lsFruit)&lt;/code>
&lt;ul>
&lt;li>unpacking: &lt;code>for ( (a, b) &amp;lt;- lsFruit )&lt;/code>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>filtering
&lt;ul>
&lt;li>&lt;code>for (f &amp;lt;- lsFruit if (f.startswith(&amp;quot;c&amp;quot;)))&lt;/code>&lt;/li>
&lt;li>&lt;code>for (n &amp;lt;- 1 to 10; e = n % 2; if e == 0)&lt;/code>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>nested for loop: &lt;code>for (i &amp;lt;- 1 to 5; j &amp;lt;- 1 to 5)&lt;/code>
&lt;ul>
&lt;li>&lt;code>to&lt;/code> in Scala is different from Python: &lt;code>1 to 5&lt;/code> gives 1, 2, 3, 4, 5&lt;/li>
&lt;li>&lt;code>until&lt;/code> in Scala is the same with Python: &lt;code>1 until 5&lt;/code> gives 1, 2, 3, 4&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="function-vs-method">function vs method&lt;a class="anchor" href="#function-vs-method">#&lt;/a>&lt;/h3>
&lt;ul>
&lt;li>function is a complete object, that can be assigned to a variable&lt;/li>
&lt;li>method is a part of a class which has a name ans signature&lt;/li>
&lt;li>void function: return Unit&lt;/li>
&lt;/ul>
&lt;h3 id="special-function">special function&lt;a class="anchor" href="#special-function">#&lt;/a>&lt;/h3>
&lt;ul>
&lt;li>call by value vs call by name&lt;/li>
&lt;/ul>
&lt;pre tabindex="0">&lt;code>def something() = {
 5 // return value
}
de callByValue(x: Int) = { // something is run once, and pass return value &amp;#34;5&amp;#34; to x
 println(&amp;#34;x1 = &amp;#34; + x)
 println(&amp;#34;x2 = &amp;#34; + x)
}
callByValue(something())
def callByName(x: =&amp;gt; Int) = {
 println(&amp;#34;x1 = &amp;#34; + x) // something ran once
 println(&amp;#34;x2 = &amp;#34; + x) // something ran again
}
callByName(something())&lt;/code>&lt;/pre>&lt;ul>
&lt;li>anonymous function&lt;/li>
&lt;/ul>
&lt;pre tabindex="0">&lt;code>((x: Int) =&amp;gt; x + 1)(5) //&amp;gt; res0: Int = 6&lt;/code>&lt;/pre>&lt;ul>
&lt;li>high order function&lt;/li>
&lt;/ul>
&lt;pre tabindex="0">&lt;code>var y = 5
val f = (x: Int) =&amp;gt; (x + y) // here, y is going to use y=5 which already exists&lt;/code>&lt;/pre>&lt;h3 id="decision">decision&lt;a class="anchor" href="#decision">#&lt;/a>&lt;/h3>
&lt;ul>
&lt;li>&lt;code>if&lt;/code>&lt;/li>
&lt;li>&lt;code>match&lt;/code> = case/switch&lt;/li>
&lt;/ul>
&lt;h3 id="set-and-map">set and map&lt;a class="anchor" href="#set-and-map">#&lt;/a>&lt;/h3>
&lt;ul>
&lt;li>both immutable&lt;/li>
&lt;li>set: automatically unique&lt;/li>
&lt;li>map: key to value pairs
&lt;ul>
&lt;li>&lt;code>var m = Map(&amp;quot;key1&amp;quot;-&amp;gt;value1, &amp;quot;key2&amp;quot;-&amp;gt;value2)&lt;/code>&lt;/li>
&lt;li>add new item: `m += “key3”-&amp;gt;value3&lt;/li>
&lt;li>remove item: &lt;code>m -= &amp;quot;key1&amp;quot;&lt;/code>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h3 id="array">array&lt;a class="anchor" href="#array">#&lt;/a>&lt;/h3>
&lt;ul>
&lt;li>index by numbers from 0&lt;/li>
&lt;li>&lt;code>var a = Array[String](6)&lt;/code>&lt;/li>
&lt;/ul>
&lt;h3 id="list">list&lt;a class="anchor" href="#list">#&lt;/a>&lt;/h3>
&lt;ul>
&lt;li>immutable&lt;/li>
&lt;li>concatenate use &lt;code>:::&lt;/code>&lt;/li>
&lt;/ul>
&lt;h3 id="class">class&lt;a class="anchor" href="#class">#&lt;/a>&lt;/h3>
&lt;ul>
&lt;li>case class&lt;/li>
&lt;/ul>
&lt;h3 id="singleton-object">singleton: object&lt;a class="anchor" href="#singleton-object">#&lt;/a>&lt;/h3>
&lt;ul>
&lt;li>object: create a anonymous class and one of its instance&lt;/li>
&lt;/ul></description></item><item><title>WSL (Windows Subsystem Linux) Tips</title><link>https://jimwang99.github.io/posts/tools/wsl-windows-subsystem-linux-tips/</link><pubDate>Tue, 25 Apr 2017 00:00:00 +0000</pubDate><guid>https://jimwang99.github.io/posts/tools/wsl-windows-subsystem-linux-tips/</guid><description>&lt;h2 id="to-start-gnome-terminal-on-wsl-windows-subsystem-for-linux">To start gnome-terminal on WSL (Windows Subsystem for Linux)&lt;a class="anchor" href="#to-start-gnome-terminal-on-wsl-windows-subsystem-for-linux">#&lt;/a>&lt;/h2>
&lt;p>After upgrade to Windows 10 Creators Update, reinstall WSL will have Ubuntu 16.04.2 LTS on Windows.&lt;/p>
&lt;p>To reinstall WSL you should do:&lt;/p>
&lt;pre tabindex="0">&lt;code>&amp;gt; lxrun /uninstall /full
&amp;gt; lxrun /install&lt;/code>&lt;/pre>&lt;p>Then you will see&lt;/p>
&lt;pre tabindex="0">&lt;code>&amp;gt; lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.2 LTS
Release: 16.04
Codename: xenial&lt;/code>&lt;/pre>&lt;p>Some X11 apps like xclocks works fine with Xming, but “gnome-terminal” still have some problem.&lt;/p></description></item><item><title>Install Python Offline</title><link>https://jimwang99.github.io/posts/tools/install-python-offline/</link><pubDate>Mon, 24 Apr 2017 00:00:00 +0000</pubDate><guid>https://jimwang99.github.io/posts/tools/install-python-offline/</guid><description>&lt;p>In general, things like Anaconda Server are designed to make this sort of workflow easier.&lt;/p>
&lt;p>Some suggested workarounds:&lt;/p>
&lt;ul>
&lt;li>Reproduce your install on another machine with internet (save conda list –export to a file and conda install –file). Then use conda update on that machine to generate and download the packages. One tip that could be helpful is if you take several conda packages and tar them up into a flat tarball you can use conda to install that tarball and it will install all the packages. Or you can put the packages in the pkgs cache and use the –offline flag.&lt;/li>
&lt;li>Install the newer Anaconda to a different location and copy the packages from the pkgs cache to your current folder.&lt;/li>
&lt;li>Both of these are a bit clunky, but there’s no easy way to achieve this without Anaconda Server.&lt;/li>
&lt;/ul></description></item><item><title>Python and Freemind ElementTree</title><link>https://jimwang99.github.io/posts/tools/python-and-freemind-elementtree/</link><pubDate>Sun, 19 Jul 2015 00:00:00 +0000</pubDate><guid>https://jimwang99.github.io/posts/tools/python-and-freemind-elementtree/</guid><description>&lt;p>我曾经自己用Python写过一个小工具来parse Freemind文件（XML格式）然后生成RestructureText和Latex格式。这个小工具的目的是为了实践我的“源文件唯一”的理念。因为我的简历（包括既往项目总结）需要保存为两种不同格式，一个为了放在个人网站上所以是HTML，另一个当然是PDF格式。&lt;/p>
&lt;p>今天瞎琢磨的时候发现，其实Python对于XML文件格式支持的极好。&lt;a href="https://docs.python.org/2/library/xml.etree.elementtree.html#module-xml.etree.ElementTree">The ElementTree XML API&lt;/a>这个模块将XML parse成一个Tree。&lt;/p>
&lt;pre tabindex="0">&lt;code>Each element has a number of properties associated with it:
 a tag which is a string identifying what kind of data this element represents (the element type, in other words).
 a number of attributes, stored in a Python dictionary.
 a text string.
 an optional tail string.
 a number of child elements, stored in a Python sequence&lt;/code>&lt;/pre>&lt;p>Python的Markdown也能够utilize这个ElementTree模块。它能够将Markdown文件Parse成eTree（也能够在之前和之后加上其他的process，以callback的形式存在）。&lt;/p></description></item><item><title>A simple system metric collector</title><link>https://jimwang99.github.io/posts/tools/a-simple-system-metric-collector/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://jimwang99.github.io/posts/tools/a-simple-system-metric-collector/</guid><description>&lt;p>&lt;a href="https://github.com/jimwang99/jimon">https://github.com/jimwang99/jimon&lt;/a>&lt;/p>
&lt;p>While experimenting my little distributed storage system built with Raspberry Pi SBCs and Ceph, some Raspberry Pi machines die now and then. My suspicion is heat, because I built them with cases, even though the cases come with attached heat sinks and fans. Therefore I built this small open-source project to help me collect system metrics periodically on Linux and send them to a server. The server store the metrics in a SQLite3 database, so that I can use a Python script to pull them out and check my small servers&amp;rsquo; status and if they died what is the cause.&lt;/p></description></item><item><title>Ceph on Raspberry Pi (1) Create Storage Cluster</title><link>https://jimwang99.github.io/posts/tools/ceph-on-raspberry-pi-1-create-storage-cluster/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://jimwang99.github.io/posts/tools/ceph-on-raspberry-pi-1-create-storage-cluster/</guid><description>&lt;p>Trying to follow this tutorial to create a Ceph distributed storage system in my home lab, because I&amp;rsquo;m sick of the NFS performance of my Synology NAS.
&lt;a href="https://ceph.io/en/news/blog/2022/install-ceph-in-a-raspberrypi-4-cluster/">https://ceph.io/en/news/blog/2022/install-ceph-in-a-raspberrypi-4-cluster/&lt;/a>&lt;/p>
&lt;h2 id="prepare">Prepare&lt;a class="anchor" href="#prepare">#&lt;/a>&lt;/h2>
&lt;h3 id="prepare-ubuntu-2004">Prepare Ubuntu 20.04&lt;a class="anchor" href="#prepare-ubuntu-2004">#&lt;/a>&lt;/h3>
&lt;p>Download ubuntu server 20.04 for Raspberry Pi (arm64 architecture)&lt;/p>
&lt;pre tabindex="0">&lt;code>sudo apt install -y python3 systemd docker.io chrony lvm2 cephadm ceph-common&lt;/code>&lt;/pre>&lt;h3 id="prepare-usb-storage">Prepare USB storage&lt;a class="anchor" href="#prepare-usb-storage">#&lt;/a>&lt;/h3>
&lt;h2 id="install-ceph-use-cephadm">Install Ceph use &lt;code>cephadm&lt;/code>&lt;a class="anchor" href="#install-ceph-use-cephadm">#&lt;/a>&lt;/h2>
&lt;h3 id="bootstrap-on-the-admin-host">&lt;code>bootstrap&lt;/code> on the admin host&lt;a class="anchor" href="#bootstrap-on-the-admin-host">#&lt;/a>&lt;/h3>
&lt;blockquote class='book-hint '>
&lt;p>On admin host&lt;/p>&lt;/blockquote>&lt;p>Here my admin host&amp;rsquo;s IP address is 192.168.68.65&lt;/p></description></item><item><title>Ceph on Raspberry Pi (2) Create Block Device</title><link>https://jimwang99.github.io/posts/tools/ceph-on-raspberry-pi-2-create-block-device/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://jimwang99.github.io/posts/tools/ceph-on-raspberry-pi-2-create-block-device/</guid><description>&lt;p>Taking my home lab Ceph distributed storage system on Raspberry Pi to the next level: make it useful by creating a block device interface so that Linux system can mount it and use it.&lt;/p>
&lt;h2 id="enable-client">Enable client&lt;a class="anchor" href="#enable-client">#&lt;/a>&lt;/h2>
&lt;ol>
&lt;li>Install Ceph package on client&lt;/li>
&lt;/ol>
&lt;pre tabindex="0">&lt;code>sudo apt install ceph-common&lt;/code>&lt;/pre>&lt;ol start="2">
&lt;li>Generate config and keyring on admin host&lt;/li>
&lt;/ol>
&lt;pre tabindex="0">&lt;code>sudo ceph config generate-minimal-conf
sudo ceph auth get-or-create client.fs&lt;/code>&lt;/pre>&lt;ol start="3">
&lt;li>Copy generated config file and keyring file from admin host to client. Config file is at &lt;code>/etc/ceph/ceph.conf&lt;/code>, keyring file is at &lt;code>/etc/ceph/ceph.client.admin.keyring&lt;/code>&lt;/li>
&lt;/ol>
&lt;h2 id="create-ceph-block-device">Create Ceph block device&lt;a class="anchor" href="#create-ceph-block-device">#&lt;/a>&lt;/h2>
&lt;h3 id="create-pool-for-rbd-rados-block-device">Create pool for RBD (RADOS Block Device)&lt;a class="anchor" href="#create-pool-for-rbd-rados-block-device">#&lt;/a>&lt;/h3>
&lt;p>On admin host:&lt;/p></description></item><item><title>Monorepo vs. Microrepo (ByteByteGo)</title><link>https://jimwang99.github.io/posts/tools/monorepo-vs-microrepo-bytebytego/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://jimwang99.github.io/posts/tools/monorepo-vs-microrepo-bytebytego/</guid><description>&lt;blockquote class='book-hint '>
&lt;p>All the credit goes to ByteByteGo.com&lt;/p>&lt;/blockquote>&lt;p>Do you believe that Google, Meta, Uber, and Airbnb put almost all of their code in one repository?&lt;/p>
&lt;p>This practice is called a monorepo.&lt;/p>
&lt;p>Monorepo vs. Microrepo. Which is the best? Why do different companies choose different options?&lt;/p>
&lt;p>Monorepo isn&amp;rsquo;t new; Linux and Windows were both created using Monorepo. To improve scalability and build speed, Google developed its internal dedicated toolchain to scale it faster and strict coding quality standards to keep it consistent.&lt;/p></description></item></channel></rss>