November 9, 2025

Your Brain Needs Fresh Air: The Hidden Reason Exercise Makes You Feel Amazing

We all know exercise is good for us, but here's what your gym might not tell you: the biggest benefit might not be the workout itself—it's the fresh oxygen flooding your system.

Think about it. The activities that make us feel most alive—hiking, swimming, skiing, even a simple walk—all happen outdoors. That's not a coincidence.

 

The Indoor Crisis We Don't Talk About

The average person spends 90% of their time indoors, breathing air that contains:

  • 2-5x more pollutants than outside air
  • Higher CO2 levels that literally make you think slower
  • Recycled pathogens and off-gassing chemicals

Studies show just 90 minutes in nature reduces activity in your brain's rumination center—that part that keeps you stuck in negative thought loops. Meanwhile, prolonged indoor time increases depression risk by 60%.

 

Your Body is Starving for Real Air

When you exercise outdoors, you're not just burning calories. You're:

  • Supercharging your mitochondria with oxygen
  • Bathing in negative ions from natural environments
  • Absorbing phytoncides from trees that boost immune function
  • Breaking the rumination cycle that indoor living enables

Research proves that "green exercise" outperforms indoor workouts for mood, energy, and cognitive function.

 

The Simple Fix That Changes Everything

You don't need a gym membership. You need fresh air.

 

Start Small:

  • Morning oxygen boost: 5 minutes outside before checking your phone
  • Lunch break reset: Walk around the block instead of scrolling
  • Evening wind-down: 10 minutes of outdoor breathing before bed

Level Up:

  • Exercise outdoors at least 3x per week
  • Work near an open window when possible
  • Take calls while walking outside
  • Eat one meal outdoors daily

Your 7-Day Challenge

For one week:

  1. Track your outdoor time
  2. Replace one indoor activity with its outdoor version daily
  3. Notice your energy, mood, and sleep

Most people report feeling dramatically different within 72 hours.

 



What indoor activity will you move outside today? Share your experience and inspire others to reclaim their right to fresh air.

October 17, 2025

AWS Q CLI Zsh setting

 

If you want to pull in your local .zshrc settings for each shell launch, you can follow the following steps:
  1. copy the following content to a new file named "myzsh" and put it somewhere in your local bin folder. I put it under ~/bin/myzsh
#!/bin/zsh # More robust wrapper that handles -c flag properly if [[ "$1" == "-c" ]]; then source ~/.zshrc eval "$2" else # Fallback to regular zsh behavior exec zsh "$@" fi
2.
chmod +x ~/bin/myzsh export AMAZON_Q_CHAT_SHELL="$HOME/bin/myzsh"
And use q chat as you normally do. in my case, it was able to see all the aliases I defined in my .zshrc file while before doing this it couldn't see them.

October 3, 2025

How to decouple MCP servers from the MCP clients.



You can easily decoulple your MCP servers from your MCP clients with the existing stdio <-> tcp tool, such as ncat (which is part of the nmap tool). Without any code changes to the existsing MCP servers available, you can serve them on a TCP port. For example, this is how I run the filesystem MCP server

ncat -lkp 7002 -e "/usr/local/bin/npx -y @modelcontextprotocol/server-filesystem /tmp"

On the mcp client side (such as Claude desktop or Cline), you would simply run another ncat as client to connect to the server

ncat 127.0.0.1 7002

That’s all. now you are serving MCP server over the network. Of course you can run multiple MCP servers on different ports.

on MacOS, you can install nmap with brew: brew install nmap



September 28, 2025

how to view a text file with multiple color highlights

Use the "rg -p" (like grep) command to search for the term and use the option `--color 'match:fg:COLOR` to specify the color. You can chain multiple rg commands. Then at the end use "less -R" to view the output. 

 

For example, the following command search within the bible, highlight the search term, but also highlights the book/verse of the line

 

rg -p $1 ~/Downloads/esv-bible-2001.txt \

| rg --colors 'match:fg:magenta' -p ':[0-9]*[A-Za-z]+ [0-9]+:[0-9]+' \

| less -R 

January 3, 2022

AWS Cost EC2-Other

 It usually consists the following cost:

1. EBS volumes
2. Nat Gateway
3. EBS snapshots
4. Idle Elastic IPs
5. Data transfer 

 

December 8, 2021

macos brew install java11

 brew install java11

sudo ln -sfn /usr/local/opt/openjdk@11/libexec/openjdk.jdk /Library/Java/JavaVirtualMachines/openjdk.jdk


August 31, 2020

openssl ssl version number interpretation


in file: usr/include/openssl/opensslv.h     of openssl source code.                                                                                                         

/*-
 * Numeric release version identifier:
 * MNNFFPPS: major minor fix patch status
 * The status nibble has one of the values 0 for development, 1 to e for betas
 * 1 to 14, and f for release.  The patch level is exactly that.
 * For example:
 * 0.9.3-dev      0x00903000
 * 0.9.3-beta1    0x00903001
 * 0.9.3-beta2-dev 0x00903002
 * 0.9.3-beta2    0x00903002 (same as ...beta2-dev)
 * 0.9.3          0x0090300f
 * 0.9.3a         0x0090301f
 * 0.9.4          0x0090400f
 * 1.2.3z         0x102031af


To get the above version number, you can all the following function: 
#include <openssl/opensslv.h>
#include <openssl/crypto.h>
void ssl_get_version(void) {
    printf ("Using OpenSSL version %u\n", OpenSSL_version_num());
}

August 16, 2020

ffmpeg command for generating Amazon Ads video

 ffmpeg -i videoSharingFinalOutput.MOV -profile:v main -r 25 -vf scale=1280:720 output.mp4

July 21, 2020

Golang short variable declaration gotcha

Golang allows short variable declaration in the form of i:=0, which defines a integer variable i. Golang also allows multi-variable short declaration, e.g.

i,j := 0,1

In this case, as long as there is one new variable on the left side, for example, i, the compiler would be happy. However, if j is not defined in the SAME BLOCK SCOPE, a new j will be created! Most times this is not what you want. Got to be very careful with that. A full example:

func test(){
    j:=1;
    if j==1 {
        i,j:=2,3
    }
    fmt.Println(j) // j is still 1!!
}

June 26, 2020

Golang range gotcha

In golang, when you range through an array of elements as in the following:

// THIS CODE IS WRONG; DO NOT USE THIS
for i,v := range elements {
    go do_something(v)
}

In the above example, the value of v may change while do_something tries to used it. This is a race condition and will definitely cause problem. To fix this, one should use elements[i] instead;

June 12, 2020

Vim typescript jump-to-definition

  1. Use vim 8.1 or newer (in older version of vim, tagstack doesn’t work with the solution below)
  2. Install ALE https://github.com/dense-analysis/ale
  3. bind Ctrl-] to ALEGoToDefinition using the following snippet of code
function ALELSPMappings()
    let l:lsp_found=0
    for l:linter in ale#linter#Get(&filetype) | if !empty(l:linter.lsp) | let l:lsp_found=1 | endif | endfor
    if (l:lsp_found)
        nnoremap <buffer> <C-]> :ALEGoToDefinition<CR>
        nnoremap <buffer> <C-^> :ALEFindReferences<CR>
    else
        silent! unmap <buffer> <C-]>
        silent! unmap <buffer> <C-^>
    endif
endfunction
autocmd BufRead,FileType * call ALELSPMappings()
  1. install tsserver if you have not done so using npm
  2. Done.

June 11, 2020

AWS API Gateway Wildcard Path

In API Gateway configuration, typically one specifies an complete API Path, such as /api/v1/fruits/list. Sometimes, it may be necessary to specify a wildcard path that includes multiple complete API paths. This is how you can do it.

  1. Use curly brackets. Specify /api/v1/fruits/{action} to allow any action to be accepted. Action can be any valid URL path segment, but it only covers one depth. It does not cover deeper URL like api/v1/fruits/list/all.
  2. To cover all sub-links, use {proxy+}. The + sign tells API Gateway to accept all sub-links.
  3. Note that you need a separate API for the root path itself, in this case /api/v1/fruits needs its own API. It’s possible to use /api/v1/fruits/{action?} to cover the root path. Needs to be verified since it’s not in the documentation.
  4. In GoLang, the wildcard value is passed to the Lambda handler in a string-to-string map named PathParameters. PathParameters:map[string]string{"id":"234"}

See more at https://aws.amazon.com/blogs/aws/api-gateway-update-new-features-simplify-api-development/

May 4, 2020

gitconfig

[user]
    name = MY NAME
    email = MY EMAIL
[core]
    editor = vim
    whitespace = cr-at-eol
[merge]
    tool = vimdiff
[alias]
    vimdiff = difftool
    st = status -sb
    ci = commit -a
    br = branch
    co = checkout
    df = diff --ignore-space-at-eol -w -b
    dc = diff --cached
    dl = diff --name-only
    last = log -1 HEAD --stat
    lg = log --stat
    lb = log --graph --oneline --decorate --date=short --pretty=format:'%C(yellow)%h %Cred%ad %Cblue%an%Cgreen%d %Creset%s' --date=relative master..
    tr = log --graph --oneline --decorate --all --date=short --pretty=format:'%C(yellow)%h %Cred%ad %Cblue%an%Cgreen%d %Creset%s' --date=relative
    tr1 = log --graph --oneline --decorate --date=short --pretty=format:'%C(yellow)%h %Cred%ad %Cblue%an%Cgreen%d %Creset%s'
    h =   log --color --date=short --pretty=format:\"%C(yellow)%h%C(reset) %s%C(bold red)%d%C(reset) %C(green)%ad%C(reset) %C(blue)[%an]%C(reset)\"  --decorate
    who = shortlog -s --
    out = log origin/master..master
    in = "!git fetch; git log master..origin/master"
    unstage = reset HEAD --
    root="rev-parse --show-toplevel"
[diff]
    renames = copy
    tool = vimdiff
[difftool "vimdiff"]
    cmd = "vim -d" "$LOCAL" "$REMOTE"
    prompt = false
[push]
    default = simple
[sendpack]
    sideband = false
[pager]
    status = true
[fetch]
    prune = true

November 6, 2019

AWS API Gateway can be expensive

As of 2019/11, AWS charges $0.25 per million connection minutes. That sounds very innocent, but is it?

If your business grows and you have up to 1 million devices that needs to keep connected to an AWS Gateway, the cost, every month, just for the connection fee would be:

$0.25*1440*30*1M/1M = $10,800 per month

In this case, a highly available cluster may be a lot more cost effective.

October 30, 2019

AWS VPC: Private Subnet vs Public Subnet

In AWS, a private subnet is defined as a subnet that doesn’t have a direct route to the Internet. It is only accessible from within the subnet, e.g. web server accessing internal database servers. If instances inside the private subnet needs to go out to the Internet, for example, updating packages, it will need to hop through a machine inside the public subnet. This can be done by a NAT instance (a dedicated instance just for this purpose) or by a NAT gateway ( a managed service provided by AWS).
Public Subnet Private Subnet
Instances have public IP addresses Instances do not have public IP address (selectable during instance creation)
Route table attached to the subnet has a default route Route table attached to the subnet has no default route

Internet Gateway

AWS Internet Gateway is a one-to-one private IP to public IP NAT device/service, not a regular NAT device like a home router. Instances inside the VPC subnet needs to have a public IP address associated with it. If not, Internet Gateway would not be able to route traffic for it.

Egress-only Internet Gateway

IPv6 Only

NAT gateway or NAT Instance

IPv4 Only

Internet Access for Default and Nondefault VPCs

The following table provides an overview of whether your VPC automatically comes with the components required for internet access over IPv4 or IPv6.

Component Default VPC Nondefault VPC
Internet gateway Yes Yes, if you created the VPC using the first or second option in the VPC wizard. Otherwise, you must manually create and attach the internet gateway.
Route table with route to internet gateway for IPv4 traffic (0.0.0.0/0) Yes Yes, if you created the VPC using the first or second option in the VPC wizard. Otherwise, you must manually create the route table and add the route.
Route table with route to internet gateway for IPv6 traffic (::/0) No Yes, if you created the VPC using the first or second option in the VPC wizard, and if you specified the option to associate an IPv6 CIDR block with the VPC. Otherwise, you must manually create the route table and add the route.
Public IPv4 address automatically assigned to instance launched into subnet Yes (default subnet) No (nondefault subnet)
IPv6 address automatically assigned to instance launched into subnet No (default subnet) No (nondefault subnet)



October 17, 2019

R ggplot2 geom_bar order

In R, to plot a pie chart using a dataframe as the data source, one would use geom_bar first to plot a bar graph, and then use coord_polar to convert it to a pie chart. It works, but there is a catch:
  • geom_bar sorts the fill value alphabetically and always put the lowest value one on the top of the bar graph. For example, “apple” would be on the top of “pear”. This becomes a problem if you intend to label the pie chart.
  • The solution is to sort the dataframe in decreasing order by the fill variable. This way all calculations will be right.

Example R code with correct labels.

df=data.frame(val=c("z","b","c"),c2=c("b","d","f"),Freq=c(5,3,4))

df=df[order(df$val,decreasing=T),]
df$Label <- paste(df$val, paste(round((df$Freq/sum(df$Freq))*100,0),"%",sep=""), sep="-")
p <- ggplot(df,aes(x=1,y=Freq,fill=val))+geom_bar(stat="identity", color = "black")
p1 <- p + coord_polar(theta='y') + theme(axis.ticks=element_blank(),
                                axis.text.y=element_blank(),
                                axis.text.x=element_text(colour='black'),
                                axis.title=element_blank())
p2 <- p1 + scale_y_continuous(labels= df$Label,breaks=cumsum(df$Freq) - df$Freq/ 2)
p3 <- p2 + labs(title=title,fill=legend_title)+theme(plot.title = element_text(hjust = 0.5))
print(p3)

Update on 10/23/2019

This article explains the order issue very clearly:

https://sebastiansauer.github.io/ordering-bars/

In short, the rule for the sort order is:
  • if factor, the order of factor levels is used
  • if character, an alphabetical order is used
So one can change the factor order to change the plot order.

October 15, 2019

jq

jq is a very useful tool to process JSON.

The idea of jq is centered on the idea of pipe and data stream.

Note below that a JSON entity is a self-contained and complete JSON object/array.

Pipes

  • When jq is invoked, the input JSON file is parsed as one or multiple JSON entities.
    • The input file can have multiple JSON entities, separated by new lines or spaces. One stream is created for each JSON entity.
    • If multiple files are supplied to jq, each file should contain one or more self-contained JSON entities.
    • To combine all the multiple input JSON entities into one big JSON entity, pass the “–slurp” flag to jq. It will automatically create a containing JSON array and contain all input JSON entities into it. This includes the case of multiple input JSON entities in one input file, or multiple input files.
  • In short, jq is started with one or multiple data streams which are from the input JSON entities.
  • Each stream is then passed through the specified filter independently.
  • One can pass the -c (compact) flag to jq to print each stream as one line.
  • Some key concepts of the filter.
    • . means the entire input data stream
    • .[] moves into the JSON object/array one layer, and splits the data stream into multiple streams, one for each entry in the object or array. For example. {"a":1,"b":2} will broken into two data streams after passing this filter, becoming 1 and 2 respectively. Note that they are the values of the entires and are not valid JSON anymore, which is okay but needs to be noted. The same streaming-splitting will also happen for JSON arrays after passing this filter.
    • .["key"] generates one stream from the input stream. The shorthand is .key;
    • , can be used to manually generate multiple streams.
    • To collect multiple streams into one stream, one can use [ ] to generate an array, or use { } to generate an object. Note that to generate an object, one has to manually specify the keys, e.g.{"key1":.a, "key2":.b}, or use the shorthand {key1,key2} which is the same as {"key1":.key1,"key2":.key2};
    • ( ) can be used to instruct jq which part of the filter to be processed first, but it does not remove/combine/split the data streams.
    • | has lower priority than ,. Therefore, 1,2,3|3 will produce three streams first 1,2,3, respectively, and then pass each stream to the second filter 3, with the end result of 3 streams of 3. If we use (), we can change that order. 1,2,(4|3) will process 4|3 first, generating 3, then processing 1,2,3, generating exact that as 3 streams of outoput. 1|4,2,3 will process 1 first, then passing to 4,2,3 three streams, causing the ending result to be 4,2,3 3 streams.
    • The filter is not a programming language. Usually stream data is not outputted in the middle of the filter processing. It usually is only outputted at the end of the filter processing, one stream at a time.
    • One can use variable assignment such as length as $array_length | . to have jq remember a interim value and used in later stages of the filter.
    • On the very basic level, data stream is passed to each filter unchanged. For example, .|.|.|.|. is the same as .
    • map(x) takes an array as input, and outputs a new array, after running that filter for each element of the input array.
    • The select() function can be used to remove undesired streams. [1,2,3] | map(select(. >= 2)) will give you [2,3]
    • One can use if-then-else-end in the filter. Note that the else clause must be there. Sometimes the empty function can help.
    • a//b The alternative operator can also be useful. It outputs a, if a is not false or null, otherwise it outputs b.
    • input_filename can be used to find the input file name.
    • One can use numbers/objects/arrays/etc. to select results from multiple streams
  • The final out is the multiple streams, one by one.

Tags: jq

IPv6 DNS server

2600::
2600::1
2600::2

September 25, 2019

SSH: How to identify which key to use when AgentFowarding is in use

https://superuser.com/questions/273037/using-the-identityfile-directive-in-ssh-config-when-agentforwarding-is-in-use 


You can use the public part of a key to to specify which private key you want to use from the forwarded agent. This requires creating an extra file (the public part of the key) on any “intermediate” machines (machines to which you forward your local ssh-agent).
  1. Arrange for the intermediate machine to have a copy of the public part of the desired key in a convenient location (e.g. ~/.ssh/some_other_key.pub).
    From any machine that already has the public part of the key:
    scp some_other_key.pub intermediate:.ssh/
    
    or, on the intermediate machine:
    ssh-add -L | grep something_unique > ~/.ssh/some_other_key.pub
    
    You may want to edit the trailing “comment” part of the public key to better identify the key’s origin/owner/purpose (or attempt to hide the same).
  2. Use the pathname to the above public key file with -i or IdentityFile.
  3. You may also need to use IdentitiesOnly yes (in .ssh/config or -o) to keep ssh from trying to offer any additional identities from your forwarded agent.