Using computers
- 1Using browser and the Internet/the Web(395w~2m)
- 2Making a personal wiki(106w~1m)
- 3Ansible(74w~1m)
- 4Amazon Web Services(244w~2m)
- 5Moving to clouds, for old-school sysadmins(289w~2m)
- 6Deploying web applications(864w~5m)
- 7Using Java(868w~5m)
- 8Using Python(66w~1m)
- 9Software(154w~1m)
- 10Using Haskell(1098w~6m)
- 11Using Kubernetes(99w~1m)
- 12Using Trello(1076w~6m)
- 13Using XML(185w~1m)
- 14Using PostgreSQL(158w~1m)
- 15Invert screen color(15w~1m)
- 16<2019-05-19> Time to buy a new computer(107w~1m)
- 17<2019-08-20> Howto: Send gmail as namesilo email(53w~1m)
1Using browser and the Internet/the Web
- 1.1Removing nag screens(116w~1m)
- 1.2Searching the Internet(211w~2m)
- 1.3Contributing to Wikipedia(44w~1m)
- 1.4Reading Reddit in Indonesia(22w~1m)
1.1Removing nag screens
- 1.1.1How to use this(20w~1m)
- 1.1.2Make www.webtoon.com fast(49w~1m)
- 1.1.3Remove Quora nag screen(18w~1m)
- 1.1.4Remove Pinterest nag screen(8w~1m)
- 1.1.5Group Gmail mails by sender email(6w~1m)
- 1.1.6Chrome bookmarklet: Make Markdown link for page(15w~1m)
- 1.1.7tvtropes.org: show all spoilers(4w~1m)
1.1.1How to use this
Copy the respective fragments to your browser's JavaScript Console (Ctrl+Shift+J on Chromium).
Don't run codes you don't trust.
1.1.2Make www.webtoon.com fast
That website has an unacceptably slow scrolling. This script makes it fast.
Usage
Open the comic episode you want to read.
Paste this fragment into your browser's JavaScript console.
// Retain big images. Discard everything else. var images = []; document.querySelectorAll("img").forEach(function (element) { images.push(element); }); document.head.innerHTML = ""; document.body.innerHTML = ""; images.forEach(function (element) { const big = 256; const url = element.dataset.url; if (url && element.width >= big) { element.src = url; element.style.display = "block"; document.body.appendChild(element); } });
To go the the next episode, increment the
episode_no
parameter in the address bar.Notes
I tried
getEventListeners
andremoveEventListener
but they don't work.
1.1.3Remove Quora nag screen
Tested on 2017-07-08.
Not only does Quora put up a nag screen, it also disables scrolling.
document.querySelectorAll("div[id]").forEach(function (x) {
if (x.id.indexOf("signup_wall_wrapper") >= 0) { x.remove(); }
});
document.body.classList.remove("signup_wall_prevent_scroll");
1.1.4Remove Pinterest nag screen
Tested on 2018-05-13.
Type 1.
document.querySelector("[data-test-giftwrap]").remove();
Type 2.
document.querySelector("#desktopWrapper").style.position = "static";
document.querySelector("body style").remove();
document.querySelector(".FullPageModal__scroller").parentNode.remove();
1.1.5Group Gmail mails by sender email
(function () {
var group = {};
document.querySelectorAll("[email]").forEach(function (elem) {
var sender = elem.getAttribute("email");
group[sender] = 1 + (group[sender] || 0);
});
var list = [];
var sender;
var count;
for (sender in group) {
count = group[sender];
list.push([count, sender]);
}
list.sort(function (a, b) {
return -Math.sign(a[0] - b[0]);
})
return list;
})();
1.1.6Chrome bookmarklet: Make Markdown link for page
This may produce invalid Markdown. Check before you copy.
javascript:window.prompt("Copy to clipboard: Ctrl+C, Enter", "- [" + document.title + "](" + document.URL + ")");
1.1.7tvtropes.org: show all spoilers
Array.prototype.map.call(document.querySelectorAll('*'), (e) => {
e.style.display = "";
e.classList.remove("spoiler");
e.classList.remove("folder");
});
1.2Searching the Internet
<2019-02-04> For reverse image search, I find Yandex better than Bing, and Bing better than Google.
- Example search: given a text description, find related images
- Example reverse search: given an image, describe it, or find its copies on the Internet
Internet search tools in 2018
duckduckgo.com: privacy-focused search engine
- less censored than Google
- no reverse search (yet?)
google.com: biggest Internet search engine in 2018
- censored
- text search
- image search
- reverse image search
Problems
Google should rank down Pinterest.
- In my experience, Pinterest is never an authoritative nor original source.
- Google has ranked down Tumblr and Wikipedia.
Example of Google censorship (compare with DuckDuckGo):
- search terms related to pornography
- search terms related to the darknet (the hidden wiki, Tor websites)
- rhino poaching (Google favors contents against rhino poaching)
bing.com: Microsoft's answer to Google
- text search
- reverse image search
- Richard Stallman's reasons not to use Microsoft
- searx?
- startpage?
reverse search tools
- Google and Bing have reverse image search
- tineye.com: reverse image search
moomash (was "audentifi"), YouTube reverse audio search
- 2018: only works with some video formats; doesn't work for old videos
- 2018-09-15: It have gone out of business, it seems.
Shazam
- Is there anything like Shazam that takes a YouTube URL, and doesn't require me to install anything?
- http://whatpixel.com/original-source-image-search-tools/
saucenao.com: reverse image search; I use it to find images stolen from pixiv
The Internet is full of crap.
- So are libraries.
- So is the world.
- So is this website.
- Thus, you must think for yourself.
1.3Contributing to Wikipedia
- 1.3.1Beginning contributing to Wikipedia(29w~1m)
- 1.3.2What should be in user page?(14w~1m)
1.3.1Beginning contributing to Wikipedia
Don't publish anything you may regret later. Once it's on the Internet, it's forever. The Internet doesn't forget. Wikipedia is a highly crawled and archived site.
1.3.2What should be in user page?
Templates: User page, User in $country, Babel
See WP:User pages.
1.4Reading Reddit in Indonesia
- Read Reddit in Indonesia with Tor Browser.
- Pro:
- Very easy to set up, very low friction.
- Con:
- Some speed penalty.
- Should not log in.
- Pro:
2Making a personal wiki
Selection criteria:
- How many people are using it?
- How big can it grow without slowing down?
- How good is its markup?
How long will it last? How long can it operate without being obsolete? How fast do the software dependencies rot?
How long does Ubuntu maintain the repository archive of old Ubuntu versions?
http://old-releases.ubuntu.com/
- 2018-08-06: It seems that Ubuntu maintains the repositories to as far back as 2006.
- https://askubuntu.com/questions/91815/how-to-install-software-or-upgrade-from-an-old-unsupported-release
Too many choices.
- http://wiki.c2.com/?PersonalWiki
- http://wiki.c2.com/?WikiEngines
- https://www.quora.com/Whats-the-best-way-to-create-a-personal-wiki
- wikimatrix.org: compare wiki softwares
safety in numbers?
many users
few users
unknown
Avoid accidental publishing.
- Don't put anything you don't want to publish inside your Jekyll directory, no matter how convenient. Accidents happen. Humans make mistakes. Computer doesn't care.
- How to Load Disqus Comments on Demand with JavaScript
3Ansible
An inventory is a map from host alias to host address. We use those aliases to select the machines to mutate.
Ansible has two executables: ansible
and ansible-playbook
.
The ansible-playbook
takes a YAML configuration.
The ansible
executable executes one command.
The ansible
command is like a "single-task playbook".
See also man ansible
("run a task on target hosts") and man ansible-playbook
.
A machine can have many roles.
An Ansible role should be a noun phrase (web-server
), not a verb phrase (install-web-server
).
4Amazon Web Services
How do we detect if we're running on AWS?
- Question on AWS forum
Some choices:
- on instance launch time: set an environment variable in the AMI used to launch instances. This seems to be the most reliable way.
on application runtime:
- HTTP server at 169.254.169.254
- Reverse DNS lookup
/proc/xen
(if your development machine doesn't use xen)
How do we get EC2 instance metadata?
- Amazon RDS is not for scaling. It is designed to simplify operation of relational databases. It is not designed to scale relational databases horizontally.
- The write capacity does not raise in proportion to the number of machines.
Deployment with Amazon Machine Images
- We assume that the code scales horizontally.
- Install everything you need to that instance.
- Snapshot an AMI from an instance.
EC2 security notes:
- Because all instances are launched from the same image, they have the same SSH host keys. Compromising any of them will also compromise all other instances sharing the key.
- See also Amazon's notes on building shared AMIs.
How do I install AWS CLI on Ubuntu 14.04?
sudo apt-get install awscli
RDS
- In Amazon RDS PostgreSQL, slow queries are not logged by default. See RDS user guide.
- Using Route 53 for aliasing your RDS instances
- RDS best practices
Shit did happen.
A busy RDS instance got CPU-throttled (ran out of CPU credits).
- CPU credit doesn't have to reach zero in order for the instance to be throttled. Don't use CloudWatch alarm condition
CpuCredit = 0
.
- CPU credit doesn't have to reach zero in order for the instance to be throttled. Don't use CloudWatch alarm condition
A busy RDS instance got IOPS-throttled (ran out of IOPS credits).
- 2018 CloudWatch doesn't have IOPS credit metric. Can't make alarm.
- AWS Device Farm: interactive testing on real devices.
5Moving to clouds, for old-school sysadmins
The most important pages on the AWS website are the pricing pages and the technical documentation. That website has much content, but not much information, perhaps because they are not selling to sysadmins.
Amazonese | Old-school |
---|---|
Route 53 | managed DNS server |
VPC (virtual private cluster) | managed LAN (local area network) |
EC2 (elastic compute cloud) instance | managed virtual machine |
security group | managed iptables/firewall |
RDS (relational database service) | managed SQL server |
EBS (elastic block store) | managed NAS (network-attached storage) |
ELB (elastic load balancer) | managed HAProxy |
ElastiCache | managed Memcached/Redis |
Lambda | automatically turn on machines to run a piece of code, and turn off idle machines |
AWS, GCE, and Azure do the same thing you used to do. The difference is they do it on a much larger scale, and they make an API on top of it, so you can automate it, but this also mean that you can be automated away, so beware!
With this cloud stuff, you can't buy a machine and bring it to the data center. You start a machine from your computer. The machine is now virtual; it doesn't correspond to a motherboard anymore. Procuring a machine is just a few clicks on the website, or a few keystrokes on the terminal, and your machine will be running in a few minutes. What you used to do in days, now you can do in minutes.
With this cloud stuff, you can't visit the data center to restart a stuck machine. You restart it from your computer.
You're billed per hour. What was infrastructure (like roads) is now utility (like electricity).
The cloud is cheaper for bursty load with low average load. If your average load is high, old-school is cheaper.
One thing doesn't change: you still need to back up data to a safe place outside the cloud. (I'm a hypocrite; I say that but I don't do that.)
6Deploying web applications
- 6.1Formalizing deployment requirements(363w~2m)
- 6.2Design(240w~2m)
- 6.3Continuous something(14w~1m)
- 6.4Fabric vs Ansible(18w~1m)
- 6.5What is DevOps?(138w~1m)
- 6.6Haskell for devops?(13w~1m)
- 6.7Migrating running processes(4w~1m)
- 6.8Troubleshooting Dashboard: What metrics you should monitor and why?(79w~1m)
6.1Formalizing deployment requirements
What is the way to deploy web applications?
General information
- I have a Java web application.
- It compiles by
mvn package
. - Its main class is
blah
.
Network
- It listens on port 1234.
- Its URL should be
https://blah/
. - It is HTTPS only. HTTP port shouldn't be open at all.
Resource requirements and burst characteristics
- It needs 4 GB of RAM for acceptable garbage collection overhead.
- It is mostly idle, but when it bursts, it requires 4 cores.
- Ops is free to horizontally scale the stateless application server.
Assuming that I'm on either Amazon Web Services or Google Cloud Platform, how do I formalize my ops requirements in a cloud-agnostic way? The 2016 article "On Formalizing and Identifying Patterns in Cloud Workload Specifications" paywall suggests an answer:
- "Approaches include orchestration specifications CAMP [1], [2], Open-CSA, SOA-ML and USDL, and on the industrial side solutions such as Amazon CloudFormation, OpenStack Heat, Cloudify and Alien4Cloud. To consolidate and enable interoperability within this variety of approaches, a technical committee by OASIS [3] defined a standard for the Topology and Orchestration Specification of Cloud Applications (TOSCA) [4], [5], which defines guidelines and facilities for the complete specification, orchestration and configuration of complex workloads, addressing portability in heterogeneous clouds."
I assume that it suggests TOSCA.
Problem: The average person won't read a specification.
Who uses TOSCA? Who implements that? Why do I never see it on AWS or GCP? Why would they follow your standard if they are the de facto standard?
Do we need more than one cloud providers?
Tools?
- kubernetes
- keter, pm2
- Why Kubernetes is The New Application Server - RHD Blog
Why I don't use NixOS:
- NixOS is insane. Patching every software on Earth is not sustainable. NixOS is only sustainable if the upstream developers use NixOS.
- 2018-08-31: Ubuntu has old-releases.ubuntu.com. It archives things back to 2006. Ubuntu has money to host 12 years of archive. NixOS doesn't have that much money. NixOS can only afford to host 1-2 years of archive.
- NixOS (or anything else indeed) would be heaven if library writers valued backward compatibility. I want my library writers to worship backward compatibility like sysadmins worship uptime. I want them to never break things that depend on them. But my experience invalidates this hope. I've seen too many breakages.
Who uses this?
- 2013 "Towards a Formal Model for Cloud Computing" paywall
6.2Design
I agree that 2018 devops ontologies suck, but I think we shouldn't avoid ontology-based systems. The solution is not to avoid ontologies. The solution is to craft a proper ontology that is timeless and essential. This is a hard philosophical problem.
For example, the relationship between "application" and "entry point" is timeless. "Entry point" is an essential property of "application". By definition, every application has an entry point.
Every software has an implicit ontology, like it or not.
Every ontology systems that captures accident instead of essence is bound to fail. Every computer ontology system that avoids philosophical ontology (What is X? What is the timeless essence of X?) is bound to fail.
Are these related?
- WP:Existence precedes essence
- WP:Essence (probably unrelated to above)
- 2011 article "On doing ontology without metaphysics" paywall
- 2012 article "Philosophies without ontology" pdf
Philosophy is Bullshit: David Hume
- What are pseudoquestions?
How do we answer "What is X?"?
There is an easy answer for mathematics. Mathematics is unique in that its ontology is mostly a priori / by fiat: we say it exists; therefore it exists. However, would it still be the case if we didn't have languages to express it?
For the real world it's hard.
Sometimes when we ask "What is X?", we are really asking "What is X for?" instead.
How do answer "What is X?" such that the correctness/truth/relevance of the answer does not depend on time/circumstances? We don't know how to predict the far future.
6.3Continuous something
Continuous integration
Continuous delivery
The ideal workflow: Git push triggers deployment?
These pages may be outdated:
6.4Fabric vs Ansible
From the user's point of view, Fabric is a python library, whereas Ansible is YAML-driven framework.
6.5What is DevOps?
XML is not suitable for declarative DevOps. See comments in devops/example.xml. We want the declaration site of some bindings to be as close as possible to their use sites.
I'm thinking about using Dhall.
Separating Dev and Ops doesn't make sense.
Ops can't fix shitty Dev. No amount of Ops will fix stupid programming. Ops is impossible without decent Dev.
What is Google search result for "devops tools"?
API description language, application description language: WADL vs Swagger vs what else?
- https://www.w3.org/Submission/wadl/
- 2010 article "DADL: Distributed Application Description Language" pdf
ontology?
- https://devops.stackexchange.com/questions/1361/what-are-known-efforts-to-establish-devops-ontology-model
- 2016 article "Application of Ontologies in Cloud Computing: The State-Of-The-Art" pdf available
- 2015 article "Composable DevOps" paywall
- 2012 article "Towards an Ontology for Cloud Services" paywall
- 2012 article "Cloud Computing Ontologies: A Systematic Review" pdf
- 2008 article "Toward a Unified Ontology of Cloud Computing" pdf available
- https://www.skytap.com/blog/cloud-ontology/
- OASIS TOSCA; too ad-hoc?
what
- 2015 article "Composable DevOps: Automated Ontology Based DevOps Maturity Analysis" paywall
6.6Haskell for devops?
- https://www.reddit.com/r/haskell/comments/31vnos/neil_mitchell_devops_with_haskell/
- https://github.com/commercialhaskell/commercialhaskell/blob/master/taskforce/devops.md
- azubi: A simple DevOps tool which will never "reach" enterprice level.
6.7Migrating running processes
6.8Troubleshooting Dashboard: What metrics you should monitor and why?
We want to minimize what we need to see. we want the metric that predicts the most problems.
- Rising maximum latency is a sign that something is overloaded.
- Rising resource usage (CPU, memory, disk, disk queue depth) predicts rising latency.
We want the metric to help us locate problems.
When such metric deviates from baseline, we know there is problem, but where?
What other metrics should we monitor?
- HTTP 4xx and 5xx status codes and connection failures?
7Using Java
<2019-01-30> Here are some Java stuff. I used Java back in the days when I lacked self-respect. I recommend Prolog instead of Java.
- 7.1Profiling?(413w~3m)
- 7.2Using Maven(59w~1m)
- 7.3Using Gradle(311w~2m)
- 7.4<2017-02-10> Make Open Travel Alliance XML schema work with JAXB(18w~1m)
- 7.5Production command-line(48w~1m)
7.1Profiling?
How to profile a Java application startup?
- How to make a Java application wait for a debugger to attach on startup?
Speeding up Java startup
Hypothesis: IntelliJ IDEA startup is slow because it decompresses JAR. Java startup would be faster if the JARs were decompressed (created using
jar c0
).- How do we test this? Profile IntelliJ IDEA startup.
Hypothesis: The IDE would be faster if it's compiled ahead-of-time.
- Can we cache the just-in-time compilation result?
Does supercompiling the IDE affect speed?
We can use the JVM without the Java language.
Profiling
- Install NetBeans.
- Choose 'Profile' in the menu, and then 'Attach to External Process'.
- Click the down-pointing triangle on the right of the Attach button.
- Choose 'Setup Attach to Process…'.
- Select 'Manually started remote Java process'.
- Choose the remote operating system.
Follow further instructions in NetBeans.
- If you need
JAVA_HOME
on Oracle JRE 8 on Ubuntu 14.04, use/usr/lib/jvm/java-8-oracle/jre
.
- If you need
- How do I start the JVM with a profiling agent?
Let the compiler help you.
If you make your the fields of your Java class final, you will never forget to set it.
- You don't need to remember anything.
- It just won't compile.
You can have dependency injection without dependency injection container/framework.
- https://sites.google.com/site/unclebobconsultingllc/blogs-by-robert-martin/dependency-injection-inversion
- If you have so many classes that instantiating them hurts, don't create so many classes in the first place.
- Neutral article http://fabien.potencier.org/do-you-need-a-dependency-injection-container.html
- Very opinionated article, borderline fanatical http://www.yegor256.com/2014/10/03/di-containers-are-evil.html
http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/
- "In short, the problem with Service Locator is that it hides a class' dependencies, causing run-time errors instead of compile-time errors […]"
Package by feature, not by layer: http://www.javapractices.com/topic/TopicAction.do?Id=205
- Dont separate model, data, entity, accessor, and service packages; package by feature not layer
- IntelliJ IDEA can open a Maven project whose POM XML file name is not pom.xml.
JVM memory usage problem
Tuning JVM memory usage
- "Make JVM respect CPU and RAM limits" https://hub.docker.com/_/openjdk/
https://blogs.oracle.com/java-platform-group/java-se-support-for-docker-cpu-and-memory-limits
2017-02-21
- https://github.com/java-deobfuscator/deobfuscator
2017-05-20
Generating Java code
Alternatives
- Use Python to generate Java code? Python comes installed with Ubuntu.
- Use Java CodeModel to generate Java code. https://github.com/javaee/jaxb-codemodel
- Use the Haskell package
language-java
to generate Java code. - Read table metadata from DataSource, generate Java source file for Entity and DAO.
2017-05-18
- Java is procedural.
object.method(argument)
is a syntactic sugar formethod(object, argument)
.- Where should the method
m
be defined? It can be defined in botha
andb
.a.m(b)
orb.m(a)
orC.m(a,b)
? If you have to ask this, your design is wrong. Antipattern: two classes A and B with conversion from A to B and B to A?
- Solution: Delete one of them?
- http://blog.sokolenko.me/2014/11/javavm-options-production.html
MaintainJ: "We simplify the complexity of maintaining Java code"
- Watch the demo.
What does it do, as seen by programmers, in non-marketing tech-speak?
- Start/stop dumping call trace of a running JVM into a file.
- Open the dump as a sequence diagram in Eclipse.
- Some filtering.
- Jconsole to remote servers, easily | Jethro Carr
7.2Using Maven
The strength of Maven is its ecosystem. Network effect.
Maven is rigid. All projects build in the same way. If you want Maven to do something, but you can't find an example on the Internet, you should assume that it can't be done.
To compile your project, run mvn compile
.
To package your project, run mvn package
.
Maven output directory is target
.
7.3Using Gradle
Conclusion:
- I still haven't found any reason to switch from Maven to Gradle (other than "because this project is already using it").
Which version of Gradle are we talking about?
- Gradle 2.9.
What problems does Gradle solve?
- Dependency management (picking the libraries' versions and downloading the corresponding JAR files) for Java.
Do we have those problems?
- Yes. Software has external dependencies.
Does Gradle 2.9 solve those problems well?
No. Gradle 2.9's dependency resolution algorithm doesn't compute the intersection of version ranges. (Maybe now it does.)
- Why does it have this defect? Maybe Gradle developers had different priorities, or they didn't know how to do it.
- Danilo Pianini: Version ranges resolution in Gradle is insane
However, there are times we want exact versions instead of version ranges. You want deterministic builds. In this case, there's no need to compute intersections.
On the other hand, we want to benefit from library updates. Maybe there are security fixes. So we want version ranges?
- But this assumes that the library maintainer obeys Semantic Versioning.
Why are we using Gradle instead of Maven? What Maven annoyances does Gradle hide from us?
- Gradle build scripts are shorter (but IDEA autocompletes Maven pom.xml).
Why not Gradle?
Why Maven instead of Gradle?
IDEA integrates better with Maven because pom.xml is configuration, not program. (But IDEA can also open build.gradle?)
- Opening a pom.xml just works in IDEA.
How does Gradle 2.9 annoy us?
- We often have to explicitly tell Gradle 2.9 the exact versions of the libraries we want because it doesn't compute intersections properly. Maven computes intersections.
- Gradle doesn't download dependencies in parallel. (But neither does Maven.)
- Gradle 2.9 doesn't generate a useful Maven POM, only a minimally valid POM.
When should I split a Gradle subproject or a Maven module?
- When we need to reuse one subproject without the others.
- If they don't make sense separately, don't split them; it'll just slow down the build for nothing.
- The same goes for Maven modules.
Woes
- ShadowJar doesn't work with Gradle 2.13.
7.4<2017-02-10> Make Open Travel Alliance XML schema work with JAXB
Save this to a file named like BINDFILE
:
<bindings xmlns="http://java.sun.com/xml/ns/jaxb"
xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="2.1">
<bindings schemaLocation="xsd/OTA_CommonTypes.xsd">
<bindings node="//xs:attribute[@name='Value']" multiple="true">
<property name="ValueAttribute"/>
</bindings>
</bindings>
</bindings>
Then run:
xjc -b BINDFILE -d outputDir xsd/XSDFILE
7.5Production command-line
<2018-08-29> For Java enterprise/server programming, I recommend Maven instead of Gradle.
This is a command line for production. Replace variables accordingly.
java \
-Xms$heap_size \
-Xmx$heap_size \
-Xloggc:"$gc_log_file" \
-XX:+PrintGCDetails \
-classpath 'target/*:target/dependency/*' \
"$java_main_class" \
"$@"
The GC log is important. When your application is unexplainably slow, first look at the GC log: does GC take too much time? Look at the "real" time.
8Using Python
Python virtualenv is relatively forward-compatible. Don't waste time installing Python from source. Use the Python packaged with your distro, and use virtualenv. The Pip that comes with Python 3.7.0 fails because Ubuntu 14.04 OpenSSL is too old (or Python doesn't bother to maintain backward compatibility).
sudo apt-get install python-virtualenv
Create a virtualenv directory using virtualenv PATH
Note: After the directory is created, it can't be renamed.
How does python find packages?
9Software
Web development
- Set up Webpack to transpile and bundle TypeScript sources
HTML DOM, web, browser, JavaScript
Software for scientists
Legality of software
Why doesn't Facebook just keep using Apache Software License version 2.0 for React? Why does it roll out its own patent license?
- Update: Facebook has switched back to Apache-2.0.
- Autotools
Functional programming
Haskell
- https://github.com/sellout/recursion-scheme-talk/blob/master/recursion-scheme-talk.org
- https://github.com/krispo/awesome-haskell
Cabal is the key to Haskell usability and adoption?
- https://www.haskell.org/cabal/
Haskell lacks something like ruby gem, python pypi, or nodejs npm.
Pure-lang
- https://puredocs.bitbucket.io/pure.html#lazy-evaluation-and-streams
- https://bitbucket.org/purelang/pure-lang/wiki/Rewriting
- https://agraef.github.io/pure-docs/#language-and-standard-library
- https://agraef.github.io/pure-docs/pure.html#pure-overview
- https://wiki.haskell.org/Applications_and_libraries/Music_and_sound
Ungrouped
doppio, a JVM written in TypeScript, with a POSIX-compatible runtime system
My abandoned software
- These are not usable.
- Pragmatic Haskell library tries to standardize the ways of doing things.
- Try Phabricator uses Docker Compose and is bundled with Apache, PHP, and MariaDB. It worked out of the box, but it was not designed for production.
- APT manual mirror copies selected Debian packages into local directory while preserving the layout. It allows you to mirror only the packages you want.
- Haji tries to be a Java bytecode interpreter written in Haskell.
10Using Haskell
- 10.1Setting up development environment(368w~2m)
- 10.2Hackage outages(34w~1m)
- 10.3Haskell in 2018(49w~1m)
- 10.4Using GHC(3w~1m)
- 10.5what(32w~1m)
- 10.6Finding a Haskell IDE(60w~1m)
- 10.7what(13w~1m)
- 10.8what(86w~1m)
- 10.9Curating libraries(2w~1m)
- 10.10what(22w~1m)
- 10.11Haskell woes(8w~1m)
- 10.12GHC woes(33w~1m)
- 10.13People who have too much time(9w~1m)
- 10.14What's hampering Haskell adoption?(10w~1m)
- 10.15Using Cabal(382w~2m)
10.1Setting up development environment
Duplicate intersecting efforts? Too many choices?
- Why is there Haskell Platform and Haskell Stack?
- Which should we use?
Why is there haskell-lang.org and haskell.org?
- Why should I use Platform if there is Stack?
- Why should I use Stack if there is Cabal new-style?
Why Stack?
- Vetted packages?
http://www.haskellforall.com/2018/05/how-i-evaluate-haskell-packages.html
cabal new-build obviates stack?
- 10.1.1My incoherent rambling(323w~2m)
10.1.1My incoherent rambling
My old way: stack. My new way: cabal new-style. It may change again.
Install the Haskell
stack
tool.I use the manual download.
- If you want to make sure that the download isn't corrupted, check the corresponding sha256sum from GitHub releases page.
- If you don't mind sudoing, use the installer script in the documentation.
- Then I check the archive contents using
tar tzf
. - If there's no weird paths, I extract the archive with
tar xzf
. - Then I make the symbolic link
~/.local/bin/stack
. If you use the manual download, you may have to install some operating system packages.
- The list is on the install script. Search for
install_dependencies
for your distro.
- The list is on the install script. Search for
Choose a Stack solver.
Forget it. Just install GHC to home.
./configure --prefix ~/.local
make -j4 install
Which version of GHC should I use? - The one that is supported by HaRe (Haskell refactoring tool) and Leksah. - On 2018-08-20, this is 8.0.2. - Leksah requires ghc >= 8.0.2. - HaRe supports ghc <= 8.0.2. - GHC 8.0 is unacceptably slow. - Forget HaRe. We'll go with Leksah. Use GHC 8.4.3.
- The widely supported GHC version lags very much behind the latest stable GHC version. I think this may be because the GHC team is rolling out lots of breaking changes in the parser because they are working on the "Trees that grow" proposal.
Which Stackage LTS version should I use?
LTS 6.35 if GHC 7.10.3?
- It also hosts a hoogle search for searching Haskell program elements.
How to get started?
Too many choices
install using the package manager that comes with your system
- pros: least hassle
- cons: outdated software
- Stack
- Cabal
- Nix
Haskell Platform
What is your preferred way of installing Haskell?
Install
cabal-install
- Download the suitable
cabal-install
binary package from https://www.haskell.org/cabal/download.html - Extract the
cabal
binary to~/.local/bin
- Download the suitable
Install current stable release of GHC
- Download the current stable release of GHC from https://www.haskell.org/ghc/download.html
- Extract it somewhere
Follow the instructions in INSTALL file:
./configure --prefix=$HOME/.local
make -j4 install
Modify
PATH
in~/.basrhc
:- Ensure that the line
export PATH
"$PATH:$HOME/.local/bin"= is in~/.bashrc
.
- Ensure that the line
For what is the hassle?
- So that, if anything goes wrong, I can nuke it without nuking my whole operating system.
10.2Hackage outages
Hackage is Haskell package repository. Sometimes it goes down.
- How to tell Cabal to use a Hackage mirror? An instruction is on the Internet; I forgot where.
- 2018-04-13: Hackage goes down for about a day
10.3Haskell in 2018
unread, Stephen Diehl
- http://www.stephendiehl.com/posts/vim_2016.html
- http://www.stephendiehl.com/posts/vim_haskell.html
- http://www.stephendiehl.com/posts/haskell_2018.html
- https://www.reddit.com/r/haskell/comments/7wmhyi/an_opinionated_guide_to_haskell_in_2018/
- https://github.com/Gabriel439/post-rfc/blob/master/sotu.md
- https://www.reddit.com/r/haskell/comments/54fv8b/what_is_the_state_of_haskell/
- https://lexi-lambda.github.io/blog/2018/02/10/an-opinionated-guide-to-haskell-in-2018/
- Eta: Haskell on JVM
Development workflow and tools
2018
IDE (integrated development environment)
- Visual Studio Code
- Leksah
- others?
- https://github.com/haskell/haskell-ide-engine
wasted efforts?
EclipseFP, no longer developed since 2015
http://jpmoresmau.blogspot.com/2015/05/eclipsefp-end-of-life-from-me-at-least.html
He got tired of working alone. He pointed us to FPComplete ide-backend.
- ide-backend seems dead; last activity is in 2016.
cabal new-style
Companies using Haskell
things hot in 2018
Unread
10.4Using GHC
Using GHCI
- https://rybczak.net/2016/03/26/how-to-reduce-compilation-times-of-haskell-projects/
- https://stackoverflow.com/questions/15662984/speed-up-compilation-in-ghc?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa
https://www.reddit.com/r/haskell/comments/45q90s/is_anything_being_done_to_remedy_the_soul/
10.5what
- Haddock markup syntax
metaprogramming from Haskell to Haskell
- Strathclyde Haskell Enhancement
- Template Haskell
https://wiki.haskell.org/Generics
- SYB (Scrap Your Boilerplate), uniplate, etc.
What does "Avoid 'success at all costs'" mean?
Will Eta kill Frege? It's sad to see works thrown away.
10.6Finding a Haskell IDE
I haven't found a convincing IDE for Haskell.
- what IDE/editor do you use for Haskell development? : haskell
- What are powerful Haskell IDEs? - Quora
- What is the best IDE for programming in Haskell? - Quora
- Haskell ides? : haskell
- Leksah-nix fails to build on my machine (Ubuntu 14.04). There are no prebuilt binaries. Must compile from source from Hackage using Cabal.
10.7what
Enterprise Haskell?
- https://wiki.haskell.org/Enterprise_Haskell
- DSH: Database Supported Haskell https://hackage.haskell.org/package/DSH
- Distributed Systems in Haskell :: Will Yager
Alien technologies?
10.8what
- useful trick, especially helpful when abusing type classes: https://chrisdone.com/posts/haskell-constraint-trick
- https://chrisdone.com/posts/twitter-problem-loeb
- http://blog.sigfpe.com/2006/11/from-l-theorem-to-spreadsheet.html
- http://blog.sigfpe.com/2007/02/comonads-and-reading-from-future.html
Components for publish-subscribe in Haskell?
- Lennart Augustsson's Things that amuse me, Haskell module overloading
lazy: Explicit laziness for Haskell
- "This library provides laziness as an abstraction with an explicit type-signature, and it so happens that this abstraction forms a monad!"
- If Haskell were strict, what would the laziness be like?
- 2014, article, Paul Chiusano: An interesting variation on a strict by default language
- How do we all feel about laziness? : haskell
distributed functional programming?
- WP:MBrace, F#
-
- has some academic papers https://wiki.haskell.org/Cloud_Haskell
10.9Curating libraries
- https://www.reddit.com/r/haskell/comments/4ggt05/best_underrated_haskell_libraries/
- https://wiki.haskell.org/Applications_and_libraries
- https://stackoverflow.com/questions/9286799/haskell-libraries-overview-and-their-quality
10.10what
unread
- servant web framework
Salsa Haskell .NET bridge
- https://stackoverflow.com/questions/5770168/templating-packages-for-haskell
Hoogle vs Hayoo?
The hoogle on stackage.org top right text bar seems to be most complete
https://mail.haskell.org/pipermail/haskell-cafe/2013-August/109945.html
10.11Haskell woes
Exceptions?
- Module system
Read(read)
should be renamed toCoShow(coshow)
.
10.12GHC woes
- Profiling requires recompiling all transitive dependencies if they happen to be compiled without profiling.
- 10.12.1Working on GHC(19w~1m)
10.12.1Working on GHC
Beginning to work on GHC
- Please see the newcomers guide first.
GHC TDNR (type-directed name resolution)
10.13People who have too much time
- https://hackage.haskell.org/package/ImperativeHaskell
- just for curiosity https://github.com/edwinb/idris-php
10.14What's hampering Haskell adoption?
- GHC's aggressive intermodule optimization precludes prebuilt binaries.
10.15Using Cabal
Every package used by Setup.hs must have a vanilla version.
Why I encountered this error:
- I set
library-vanilla
toFalse
due to https://rybczak.net/2016/03/26/how-to-reduce-compilation-times-of-haskell-projects/
- I set
How I encountered this error:
HDBC-postgresql-2.3.2.5
Setup.hs
build fails due to linking error withshared: True
.The offending packages are
old-time
andold-locale
.- It's OK if we build them as shared library, but we must also build their vanilla version.
- It's not the library content that fails to build. It's the Cabal Setup of the library that fails to link.
- GHC expects that
old-time
andold-locale
are system libraries? - GHC passes '-lHSold-time-VERSION-HASH.so'. It passes that in the -l switch to GCC.
Cabal writes 'libHSold-time-VERSION-HASH-ghc-8.2.2.so'.
- Note the
ghc-8.2.2
part isn't in the string passed by GHC to GCC.
- Note the
- Can we solve this by
cabal install old-time old-locale
? https://github.com/haskell/cabal/issues/1720
- Workaround: Add
--ghc-options
-dynamic= to cabal new-install
- Workaround: Add
- How do we tell Cabal to use the version we installed with new-install?
- Where should we fix this? Cabal? GHC? HDBC-postgresql?
- Should we find another library? Hackage has a low-level libpgsql wrapper.
Should we just disable HDBC-postgresql on meta?
How I diagnosed it:
- Pass
-v
to GHC (create a bash script namedghc
that callsSOMEWHERE/ghc -v "$@"
, and put its directory in front ofPATH
). - Add
-v
tocabal
. Then look at this fragment. It's suspicious thatold-time
is the only package with a hash.
package flags [-package-id Cabal-2.0.1.0{unit Cabal-2.0.1.0 True ([])}, -package-id array-0.5.2.0{unit array-0.5.2.0 True ([])}, -package-id base-4.10.1.0{unit base-4.10.1.0 True ([])}, -package-id binary-0.8.5.1{unit binary-0.8.5.1 True ([])}, -package-id bytestring-0.10.8.2{unit bytestring-0.10.8.2 True ([])}, -package-id containers-0.5.10.2{unit containers-0.5.10.2 True ([])}, -package-id deepseq-1.4.3.0{unit deepseq-1.4.3.0 True ([])}, -package-id directory-1.3.0.2{unit directory-1.3.0.2 True ([])}, -package-id filepath-1.4.1.2{unit filepath-1.4.1.2 True ([])}, -package-id ghc-prim-0.5.1.1{unit ghc-prim-0.5.1.1 True ([])}, -package-id old-time-1.1.0.3-8c2cc8e5fb3b424e71501141225064c5d9ee4eeba7f40b702227ad1c3ea2c5b7{unit old-time-1.1.0.3-8c2cc8e5fb3b424e71501141225064c5d9ee4eeba7f40b702227ad1c3ea2c5b7 True ([])}, -package-id pretty-1.1.3.3{unit pretty-1.1.3.3 True ([])}, -package-id process-1.6.1.0{unit process-1.6.1.0 True ([])}, -package-id template-haskell-2.12.0.0{unit template-haskell-2.12.0.0 True ([])}, -package-id time-1.8.0.2{unit time-1.8.0.2 True ([])}, -package-id transformers-0.5.2.0{unit transformers-0.5.2.0 True ([])}, -package-id unix-2.7.2.2{unit unix-2.7.2.2 True ([])}]
- Pass
How I solved it:
I added this fragment to
cabal.project
:package old-time library-vanilla: True package old-locale library-vanilla: True
- Related
- https://github.com/haskell/cabal/issues/4748
- [#3409 Can't use system GHC without static libraries at all](https://github.com/commercialhaskell/stack/issues/3409)
- [#1720 `executable-dynamic: True` should apply to `build-type: Custom` setup](https://github.com/haskell/cabal/issues/1720)
#4506
new-haddock
's file monitoring brokennew-haddock
doesn't work afternew-build
.
#5290 new-build runs into internal error after deleting from store
- Solution: nuke the entire store:
rm -r ~/.cabal/store
.
- Solution: nuke the entire store:
Non-problems
cabal new-build --disable-optimization
doesn't disable optimization of transitive dependencies.- Cannot reproduce this in cabal 2.3. Is this a 2.0.0.1 bug?
$HOME/.cabal/config
hasoptimization: False
.- Is this a regression? Oversight? It works with
cabal install
. What I'm trying to do:
- Build transitive dependencies with optimization disabled, for faster development.
My guess:
- There seems to be a problem in how the new code path plumbs down arguments.
"Using internal setup method with build-type"
always gets argument--enable-optimization
.- That message is printed by
./Distribution/Client/SetupWrapper.hs:418
internalSetupMethod
ifcabal new-repl
is run with--verbose
. - Where does that
--enable-optimization
come from? - Why isn't the
--disable-optimization
passed down?
- That message is printed by
Related issues:
Cabal codebase
Seemingly minor codebase maintenance problems
Code duplication
CmdRepl.hs
seems to be copied fromCmdBuild.hs
.
CmdBuild.hs
imports...Orchestration
unqualified without explicit import list
Cabal description field pitfall
11Using Kubernetes
- kubernetes.io: "Production-Grade Container Orchestration"
How do we control access to Kubernetes?
- https://stackoverflow.com/questions/42170380/how-to-add-users-to-kubernetes-kubectl
- https://kubernetes.io/docs/admin/authentication/
- https://kubernetes.io/docs/admin/accessing-the-api/
- How do we add and remove users and roles to Kubernetes?
- Which is the most hassle-free future-proof minimal-maintenance way?
Kubernetes security
- https://kubernetes.io/blog/2016/08/security-best-practices-kubernetes-deployment/
- https://kubernetes.io/docs/tasks/administer-cluster/securing-a-cluster/
Which document should we read? Overlapping? Confusing?
What is Kubernetes's replacement of AWS security groups?
How I think Kubernetes fits in Google's strategy
Kubernetes commoditizes IaaS providers.
It lowers the barrier of switching from any other cloud providers to GCE.
- Examples of other cloud providers: Amazon Web Services (AWS), DigitalOcean, Alibaba Cloud (Aliyun), Microsoft Azure
The same way Microsoft Windows commoditized PC hardware.
- WP:Commoditization
- The Kubernetes Bible for Beginners & Developers - Level UpLevel Up
12Using Trello
How should we best use Trello?
- A card gathers people to help each other accomplish a common goal.
- A card disseminates information from the people who have it to the people who need it.
Traps
- Because Trello cannot collaborative edit, we must not write too long before we save. Two people must not edit the card at the same time.
What do we use Trello for?
- Prioritize what to do, starting with the highest velocity (value per effort)
- Give enough information for others to help us
What Trello is not
- A Trello column is not a mere to-do list.
- Milestone lists are better than to-do lists. Be declarative, not imperative. Describe what you want, not how you want to do it.
- If you can do it in a few hours, you don't need to make a Trello card for it.
- If you don't need help with something, don't write a Trello card for it.
Our attitude towards Trello
We should consider the time spent on Trello as overhead. We should minimize the time we are editing, moving, arranging Trello cards.
- Human nature trap: It's fun to look busy (over-organizing).
When not Slack?
- If you need to remember it later, use Trello or Confluence, not Slack.
- If a problem will take some time, don't waste your time typing on Slack. Put it in Trello, and assign it to the person who can fix it.
What is in a card?
- Write a card with the intention of helping everyone else help you. The card must answer "What can I help? How can I help?".
- A card contains information or will contain information.
A person should be in the card if:
- he person needs that information, or
- he can contribute that information (he may also contribute in a comment).
No other person should care about that card.
What is Trello?
To answer this, we answer these questions:
- What does Trello make easy?
- What does Trello make hard?
- We seek an operational definition for Trello. We define something by what it do.
What should we group together? Why?
- A board is a list of a column.
- A column is a list of cards. Trello uses the term "list", but we use "column" to avoid confusion.
- A card has zero or more members.
- A card has zero or more labels.
- A label is like an atom in propositional logic.
- The filtering system is a limited form of propositional logic.
- A card is a way for several people to share information.
- If two people need the same information, they should subscribe to the same card.
- If we need two people to finish (archive) a card, then both of those people should be members of that card.
- What is a label? You give a label L to a card if and only if you often need to filter (select) all cards labeled L.
- Why are two cards in the same list? Because they have something in common. They share something. An aspect of them is equal.
- We group something in a list to minimize moving cards.
- What is that aspect? What irreplaceable advantage does it give us?
- Because they have the same members? (We can use filter for this.) Because they belong to the same team? Because they have the same due date? (We can use filter for this.) Because they are a part of the same user story? Navigating multiple boards is hard (big cognitive burden).
- Label is for filtering.
What is easy to do in Trello?
- Toggle any of the first 10 labels.
- Show cards assigned to me (the user who is logged in).
- Show cards by a conjunction or a disjunction of a Condition.
- Condition is an element of Conditions.
- Conditions is the union of all labels in a board and members of a board.
- Click on the due date in the card description to mark it complete.
- Read card comments in reverse chronological order (newer comments first).
- Move a card to the bottom of an adjacent list.
- See the number of checked items in a checklist in a card.
- In the comment of a card, add another card.
- Trello assumes that every checklist in the item has the same effort. Therefore we must make sure that every item in a checklist in the item has the same effort.
What is a bit hard to do (because it cannot be done by keyboard alone):
- Adding a check list in a card
- A card can have many checklists
- Marking a check list in a card
- Unmarking a check list in a card
- Filtering makes navigating a large board possible.
What is hard to do in Trello:
- Move from a board to another boards. (High cognitive load due to context switching.)
- One person should not be in more than one board.
- Move a card from a list to another list. It is easier to archive the list.
- Unarchive a card
What is impossible (assuming no plugins):
- See due dates in non-US format
- Use keyboard to move card up or down in a list
- Gantt chart
- Calendars
- Progress report
- Collaboratively edit a card description. Trello will only show the last saved description. The previous descriptions are not lost, but hardly accessible. The old description can be accessed by Exporting a card as JSON.
- In a card description, we can link to a board or a card, but not link to a list.
Member vs subscribe:
- If and only if you are a member of a card, it will show in 'my card' filter (Press Q) The members of a card are the people assigned to a card We must tailor our workflow so that we use only the easy things.
Please read and memorize the Trello shortcut keys.
- Also read How to use Trello like a pro.
- Those documents reflect what the Trello designer thinks Trello is best used for.
In search of a Trello architecture
Fixed Pipeline / Mini waterfalls
- Column = team, Card = product
- One column is assembly line.
- Cards move from left to right.
- Progress is sequential. Right column cannot start before left column finishes what it has to do with the card.
- Ideal for the same process that is repeated very many times.
- For example, in our case, the columns would be Requirement, UI, Database, Backend, Frontend, Done.
Column = a rather big to-do, card = breakdown of the column
- For example, in our case, each column would be "As a (who), I (do what)".
- A column is a work item and each card in the column is a breakdown of that item.
- Column = epic / bigger user story, card = smaller user story
Column = milestone, card = breakdown of milestone
Trello list hierarchy (a Trello account is a list of lists of …)
- A Trello account is a list of boards.
- A board is a list of columns.
- A column is a list of cards.
- A card is a list of checklists.
- A checklist is a list of checklist items.
- Therefore we can use Trello for work breakdown structure of perhaps at most 4 levels deep.
13Using XML
- 13.1Finding the editor(74w~1m)
- 13.2Using schemas(48w~1m)
- 13.3Toward markup language agnosticity(64w~1m)
13.1Finding the editor
List of editors:
I have used
- Vim
- IntelliJ IDEA
I don't know
- emacs nxml-mode
- jEdit XML plugin
- QXMLEdit? Can it autocomplete?
- XML Notepad
Sources:
IntelliJ IDEA works fine, but I'd be happy if there is a lighter alternative.
My criteria:
- open-source
- schema-aware, supports XML Schema Definition (XSD)
autocompletion
- 2018-08-22
Nice-to-have features:
- Automate closing tag.
- Editing an opening tag also edits the closing tag.
- Editing a closing tag also edits the opening tag.
- Any way to avoid memorizing and typing
xmlns:xsi
.
Vim can semi-automate XML closing tag using Ctrl+P.
13.2Using schemas
In principle, from a type defined in an XSD file, we can generate a Haskell module and a Java class.
- W3C XML Schema: DOs and DON'Ts
- xsd - What are the best practices for versioning XML schemas? - Stack Overflow
- Tutorial: XML Schema Keys | XML Schema Tutorial | Webucator
13.3Toward markup language agnosticity
What is common between XML, JSON, and YAML?
Can we map (interconvert) between XML and YAML? Approximate data model:
type Key = String
type Atr = (Key, String)
data Xml
= XText String
| XElem [Atr] Name [Xml]
data Json
= JText String
| JMap [(Key, Json)]
| JList [Json]
xj :: Xml -> Json
jx :: Json -> Xml
Can we use XML Schema to validate a JSON/YAML document?
We can map a subset of XML to YAML using YAXML, the (draft) XML Binding for YAML.
14Using PostgreSQL
Questions
- How do we find slow queries?
- Which queries lock some tables or the database?
Is there a GUI or visualization tool?
- There should already be a tool for visualizing such Postgresql statistics?
- Is autovacuum enabled on our RDS clusters? How do we know?
- Do we need reliability? If we can sacrifice reliability, we can speed things up by turning fsync off.
How much performance does RDS encryption cost? Negligible, but with caveats.
Answers looking for questions
- There is a statistics collector.
- Logging Difficult Queries
- Postgresql needs regular maintenance. One critical maintenance task is to VACUUM the database; the query planner relies on VACUUM ANALYZE.
- Turning PostgreSQL into a queue serving 10,000 jobs per second
- Towards 14,000 write transactions on a laptop
- How many updates per second can a standard RDBMS process?
PostgreSQL tuning
2018-02-21
- pgbench
IN is faster than VALUES in psql 9.3
- select values & join instead of in list https://wiki.postgresql.org/wiki/Sample_Databases
- 14.1Traps, pitfalls, gotchas(24w~1m)
14.1Traps, pitfalls, gotchas
14.1.1PostgreSQL ALTER TABLE DROP COLUMN doesn't actually remove the column from disk
From PostgreSQL Tables Can Only Have 1600 Columns, Ever. | Nerderati.
15Invert screen color
https://askubuntu.com/questions/181419/how-to-reverse-colors-for-the-current-window-in-gnome-shell xcalib -invert -alter Keyboards Bind it to Super+I Bind gnome-terminal to Super+T
16<2019-05-19> Time to buy a new computer
My old computer's left DIMM socket is broken, and 4 GB RAM is somewhat restrictive.
I am looking for a laptop with these features:
- zero-maintenance
- no dust; fanless
- serviceable
- replaceable battery
- replaceable disk
- at least 8 GB RAM
- long durable battery life with adjustable full charge
- SSD, at least 64 GB; I will set up encrypted LVM and download development tools
- service center
- warranty
- quick service (solve in hours, total replacement if necessary) no matter what the problem is
- fits in my bag, easy to carry, but not too small as to be unreadable
- lightweight
- dimensions?
- no fatal negative online reviews
- not too new, lest it be defective
Indocomtech 2019 will be held in 30 October – 3 November.1
17<2019-08-20> Howto: Send gmail as namesilo email
namesilo: "Please note that we do not offer a service for sending email."2 Follow these instructions to set up gmail3.
There are two SMTP servers. Receiving and sending use different SMTP servers. Receiving email uses Emailowl SMTP, but sending email uses Gmail SMTP. Set up Gmail "app password".