Numerical Software Development
Fundamental Engineering⚓︎
Shebang⚓︎
#!/bin/bash
中的#!
。在檔案中存在Shebang的情況下,類Unix作業系統的程式載入器會分析Shebang後的內容,將這些內容作為直譯器指令,並呼叫該指令,並將載有Shebang的檔案路徑作為該直譯器的參數。
Variable⚓︎
Shell Variable (local)⚓︎
Environment Variable (global)⚓︎
Source⚓︎
dosomething.sh:
Without source(Child process cannot modify the current environment variable):Bash Session
With source(Child process can modify the current environment variable):
$ unset MYENVVAR
$ ./dosomething.sh
$ echo ${MYENVVAR:-"MYENVVAR is not set"}
do something
MYENVVAR is not set
Bash Session
$ unset MYENVVAR
$ source ./dosomething.sh
$ echo ${MYENVVAR:-"MYENVVAR is not set"}
do something
MYENVVAR is set to what I want
Redirection⚓︎
Simple Redirection⚓︎
Stdout & Stderr Redirection⚓︎
Bash Session
$ cp nothisfile.txt another.txt 2>&1 > /dev/null
cp: nothisfile.txt: No such file or directory
$ cp nothisfile.txt another.txt > /dev/null 2>&1
$ cat another.txt
cat: another.txt: No such file or directory
Stderr to Null Device⚓︎
Bash Session
$ # without redirecting stderr we see unwanted messages
$ var=$(grep impossiblestring *)
grep: bind1: Is a directory
grep: build: Is a directory
grep: gtest: Is a directory
grep: make1: Is a directory
grep: make2: Is a directory
grep: make3: Is a directory
grep: make4: Is a directory
grep: nsd: Is a directory
grep: repo1: Is a directory
$ echo $var
Bash Session
$ # throw stderr to null device and we get only the wanted information
$ var=$(grep impossiblestring * 2> /dev/null)
$ echo $var
Conditional Branching (If/Else)⚓︎
Bash
#!/bin/bash
if [[ "$(uname)" == "Darwin" ]] ; then
NP=${NP:-$(sysctl -n hw.ncpu)}
elif [[ "$(uname)" == "Linux" ]] ; then
NP=${NP:-$(cat /proc/cpuinfo | grep processor | wc -l)}
else
NP=${NP:=1}
fi
echo "NP may be set to $NP"
Function⚓︎
Bash
#!/bin/bash
runcmd () {
echo "run command: ${@:2}"
{ time "${@:2}" ; } > $1 2>&1
echo "done; log file: $(cd "$(dirname $1)" && pwd)/$1"
}
runcmd line1.log echo "first command"
runcmd line2.log echo "second command"
Bash Session
$ ./bashfunction.sh
run command: echo first command
done; log file: /Users/yungyuc/hack/code/nsd/notebook/20au_nctu/02_engineering/line1.log
run command: echo second command
done; log file: /Users/yungyuc/hack/code/nsd/notebook/20au_nctu/02_engineering/line2.log
$ cat line1.log
first command
real 0m0.000s
user 0m0.000s
sys 0m0.000s
$ cat line2.log
second command
real 0m0.000s
user 0m0.000s
sys 0m0.000s
Makeflie⚓︎
Make could trace the timestamp of the source file automatically.
Makefile Format⚓︎
Rule:
https://seisman.github.io/how-to-write-makefile/overview.htmlAutomatic Variables and Implicit Rule⚓︎
-
$@
is the file name of the target of the rule. -
$^
is the file names of all the prerequisites. -
$<
is the file name of the first prerequisite. -
%
in the target will match any non-empty characters, and it is expanded in the prerequisite.
Makefile
CXX = g++
hello: hello.o hellomain.o
$(CXX) $^ -o $@
%.o: %.cpp hello.hpp
$(CXX) -c $< -o $@
Bash Session
$ rm -f hello *.o
$ make
g++ -c hello.cpp -o hello.o
g++ -c hellomain.cpp -o hellomain.o
g++ hello.o hellomain.o -o hello
Phony targets⚓︎
CMake⚓︎
- CMake is a two-pass build tool.
- First pass reads the input file CMakeLists.txt and generates files for the second pass.
- The second pass uses a different build tool (may be make) to build the software.
- Useful for cross-platform building.
- Bash and make can handle a little bit of the cross-platform. But the if/else is not easy to maintain.
Python and Numpy⚓︎
Python⚓︎
Modeline⚓︎
vim內建的功能,可以知道程式如何排版。
One-Liner⚓︎
Module⚓︎
當python檔不是腳本時,if __main__=="name"
就不會有反應。
如果想直接執行腳本中的if __main__=="name"
。
可以使用-m
。
Bash Session
$ python3 step3/__init__.py pstake.py
Traceback (most recent call last):
File "/Users/yungyuc/work/web/ynote/nsd/02numpy/code/step3/__init__.py", line 12, in <module>
from ._core import count_line
ImportError: attempted relative import with no known parent package
$ python3 -m step3 pstake.py
811 lines in pstake.py
Note
題外話,雙底線__
的英文叫做double underscore,或是有更簡單的叫法,dunder。
Numpy⚓︎
Basic Meta-Data⚓︎
- itemsize: number of bytes of an element
-
nbytes: number of bytes of all elements
-
dtype:
dtype (object) | dtype string name | C++ type name |
---|---|---|
numpy.bool_ | "bool" | bool |
numpy.int8 | "int8" | int8_t |
numpy.int16 | "int16" | int16_t |
numpy.int32 | "int32" | int32_t |
numpy.int64 | "int64" | int64_t |
numpy.uint8 | "uint8" | uint8_t |
numpy.uint16 | "uint16" | uint16_t |
numpy.uint32 | "uint32" | uint32_t |
numpy.uint64 | "uint64" | uint64_t |
numpy.float32 | "float32" | float |
numpy.float64 | "float64" | double |
Construction⚓︎
- fulls():
Slicing⚓︎
- Copy