# The Willpower Instinct (Kelly McGonigal, 2013)
Caloni, 2025-04-29 <self> <books> <drafts> [up] [copy]Lendo este livro, mas bem lentamente. Seguem recortes.
I believe that the best way to improve your self-control is to see how and why you lose control. (...) Self-knowledge—especially of how we find ourselves in willpower trouble—is the foundation of self-control. (...) You can—and should—make yourself the subject of your own real-world study.
Your willpower challenge could be something you’ve been avoiding (“I will”) or a habit you want to break (“I won’t”) or an important goal in your life that you’d like to give more energy and focus to (“I want”). (...) To exert self-control, you need to find your motivation when it matters. This is “I want” power.
As the prefrontal cortex (walking, running, reaching, pushing) grew, it took on new control functions: controlling what you pay attention to, what you think about, even how you feel. (...) It has three key regions that divide up the jobs of I will, I won’t, and I want. (...) The more rapidly the “I want” region cells fire, the more motivated you are to take action or resist temptation. (...) The part of you that wants to give in isn’t bad—it simply has a different point of view about what matters most.
You need to recognize when you’re making a choice that requires willpower; otherwise, the brain always defaults to what is easiest. (...) When your mind is preoccupied, your impulses—not your long-term goals—will guide your choices. (...) To have more self-control, you first need to develop more self-awareness. (...) Trying to keep track of your choices reduces the number of decisions you make while distracted.
Regular meditators have more gray matter in the prefrontal cortex, as well as regions of the brain that support self-awareness. (...) One study found that just three hours of meditation practice led to improved attention and self-control. After eleven hours, researchers could see those changes in the brain. (...) It may seem incredible that our brains can reshape themselves so quickly, but meditation increases blood flow to the prefrontal cortex, in much the same way that lifting weights increases blood flow to your muscles. (...) This simple act of staying still is part of what makes meditation willpower training effective. You’re learning not to automatically follow every single impulse that your brain and body produce. (...) Notice how it feels to breathe, and notice how the mind wanders. (...) Most new meditators make this mistake, but the truth is that being “bad” at meditation is exactly what makes the practice effective. (...) Meditation is not about getting rid of all your thoughts; it’s learning not to get so lost in them that you forget what your goal is.
# O poder do silêncio (Eckhart Tolle, 2016)
Caloni, 2025-04-29 <self> <books> <drafts> [up] [copy]Mais um livro sendo relido parcialmente. Alguns recortes.
O reino da consciência é muito mais vasto do que aquilo que o pensamento é capaz de abranger.
Os dogmas são prisões formadas por conceitos coletivos. O que parece estranho é que as pessoas gostam de suas prisões, pois elas lhes dão uma sensação de segurança e uma falsa impressão de que “sabem das coisas”. (...) Qualquer tipo de preconceito mostra que você está identificado com a mente pensante. Mostra que você não está vendo o outro ser humano, está vendo apenas seu conceito sobre aquele ser humano. Reduzir uma pessoa a um conceito já é uma forma de violência.
A mente funciona com “voracidade” e por isso está sempre querendo mais. Quando você se identifica com a sua mente, fica facilmente entediado e ansioso. O tédio demonstra que a mente deseja avidamente mais estímulo, mais o que pensar, e que essa fome não está sendo saciada. (...) O tédio é simplesmente um movimento de energia condicionada dentro de você. (...) Você trata o momento atual como um obstáculo que precisa ser ultrapassado? Você considera mais importante o momento futuro que quer atingir? (...) Assumir responsabilidade por este momento presente é estar em harmonia com a vida.
Quando você passa a dar atenção ao Agora, cria-se um estado de alerta. É como se você acordasse de um sonho, o sonho do pensamento, o sonho do passado e do futuro. É tão claro e tão simples. Não sobra lugar para criar problemas. Só esse momento, tal como ele é. Quando concentra sua atenção no Agora, você se dá conta de que a vida é sagrada. Existe algo de sagrado em tudo que você percebe quando se concentra no presente. Quanto mais você viver no Agora, mais vai sentir a simples e profunda alegria de Ser e do caráter sagrado da vida.
# In Search of the Miraculous (P.D. Ouspensky, 1949)
Caloni, 2025-04-29 <self> <books> <drafts> [up] [copy]There was another type of school, with which I was unable to make contact and of which I only heard. These schools promised very much but they also demanded very much. They demanded everything at once. It would have been necessary to stay in India and give up thoughts of returning to Europe, to renounce all my own ideas, aims, and plans, and proceed along a road of which I could know nothing beforehand.
Our starting point is that man does not know himself, that he is not" (he emphasized these words), "that is, he is not what he can and what he should be. For this reason he cannot make any agreements or assume any obligations. He can decide nothing in regard to the future.
# Multiple peers Wireguard calculation
Caloni, 2025-04-30 <code> [up] [copy]/** Multiple peers Wireguard calculation. Wireguard does not support overlapping allowed ips for multiple peers. To cover all possible ips excluding others for secondary peers some calculation is needed to mount the allowed ips list derived from 0.0.0.0. @author Wanderley Caloni <wanderleycaloni@gmail.com> @date 2024-08 */ using System.Net; public class Program { private static void CalculateWireguardAllowedIps(ref HashSet<IPNetwork2> list, IPNetwork2 ip, IPNetwork2 remove) { if (ip.Cidr == 32) { if (ip != remove) { list.Add(ip); } else { Console.WriteLine("CalculateWireguardAllowedIps: found and skipping" + ip.ToString()); } } else { HashSet<IPNetwork2> split = ip.Subnet((byte)(ip.Cidr + 1)).ToHashSet(); // [0]=left, [1]=right if (split.Count == 2) { List<IPNetwork2> splitList = split.ToList(); if (splitList[0].Overlap(remove)) { list.Add(splitList[1]); CalculateWireguardAllowedIps(ref list, splitList[0], remove); } else { list.Add(splitList[0]); CalculateWireguardAllowedIps(ref list, splitList[1], remove); } } } } private static void CalculateWireguardAllowedIps(ref HashSet<IPNetwork2> ipsToAdd, ref HashSet<IPNetwork2> ipsToRemove, ref HashSet<IPNetwork2> list) { foreach (IPNetwork2 remove in ipsToRemove) { var localIpsToAdd = new HashSet<IPNetwork2>(ipsToAdd); foreach (IPNetwork2 add in localIpsToAdd) { if (add.Overlap(remove)) { CalculateWireguardAllowedIps(ref list, add, remove); } else { list.Add(add); } } ipsToAdd = list; } } private static void AddAllowedIp(ref HashSet<IPNetwork2> allowedIps, IPNetwork2 addThisIp, ref HashSet<IPNetwork2> notAddTheseIps) { if (addThisIp.Cidr == 32) { if( ! notAddTheseIps.Contains(addThisIp)) { allowedIps.Add(addThisIp); } else { Console.WriteLine("AddAllowedIp: found and skipping " + addThisIp.ToString()); } } else { List<IPNetwork2> split = addThisIp.Subnet((byte)(addThisIp.Cidr + 1)).ToList(); // [0]=left, [1]=right if (split.Count == 2) { bool overlapLeft = false, overlapRight = false; foreach(IPNetwork2 notIp in notAddTheseIps) { if (split[0].Overlap(notIp)) { overlapLeft = true; } if (split[1].Overlap(notIp)) { overlapRight = true; } if( overlapLeft && overlapRight) { break; } } if (overlapLeft) { AddAllowedIp(ref allowedIps, split[0], ref notAddTheseIps); } else { allowedIps.Add(split[0]); } if (overlapRight) { AddAllowedIp(ref allowedIps, split[1], ref notAddTheseIps); } else { allowedIps.Add(split[1]); } } } } public static int Main(string[] args) { HashSet<IPNetwork2> twoPeersHashSet = new HashSet<IPNetwork2>(); IPNetwork2 allAllowedIPs = new IPNetwork2(IPAddress.Parse("0.0.0.0"), 0); IPNetwork2 removeIP = new IPNetwork2(IPAddress.Parse("66.22.190.0"), 32); CalculateWireguardAllowedIps(ref twoPeersHashSet, allAllowedIPs, removeIP); HashSet<IPNetwork2> multiplePeersHashSet = new HashSet<IPNetwork2>(); HashSet<IPNetwork2> ipsToRemove = new HashSet<IPNetwork2>(); //ipsToRemove.Add(new IPNetwork2(IPAddress.Parse("66.22.190.0"), 32)); ipsToRemove.Add(new IPNetwork2(IPAddress.Parse("66.22.188.1"), 32)); //ipsToRemove.Add(new IPNetwork2(IPAddress.Parse("66.22.190.1"), 32)); //ipsToRemove.Add(new IPNetwork2(IPAddress.Parse("66.22.188.0"), 32)); AddAllowedIp(ref multiplePeersHashSet, allAllowedIPs, ref ipsToRemove); var inMultipleExceptTwoPeers = multiplePeersHashSet.Except(twoPeersHashSet).ToHashSet(); var inTwoPeersExceptMultiple = twoPeersHashSet.Except(multiplePeersHashSet).ToHashSet(); Console.WriteLine("In multiple peers except two peers:"); foreach (var ip in inMultipleExceptTwoPeers) { string s = "ips in " + ip.ToString() + ": "; foreach(var ip2 in ip.ListIPAddress() ) { s += ip2.ToString() + " "; } Console.WriteLine(s); } Console.WriteLine("In two peers except multiple peers:"); foreach (var ip in inTwoPeersExceptMultiple) { string s = "ips in " + ip.ToString() + ": "; foreach(var ip2 in ip.ListIPAddress() ) { s += ip2.ToString() + " "; } Console.WriteLine(s); } return 0; } }
# Set the Windows console to full screen
Caloni, 2025-04-30 <code [up] [copy]#include <iostream> #include <windows.h> int main() { if( ! SetConsoleDisplayMode(GetStdHandle(STD_OUTPUT_HANDLE), CONSOLE_FULLSCREEN_MODE | CONSOLE_WINDOWED_MODE, NULL) ) { // if GetLastError 120 use this: ::SendMessage(::GetConsoleWindow(), WM_SYSKEYDOWN, VK_RETURN, 0x20000000); } system("chcp 65001"); // utf-8 }
# Desafio 5
Caloni, 2025-04-30 <code> [up] [copy]/** My solution to the infamous desafio05 from the site Os Programadores. @author Wanderley Caloni <wanderleycaloni@gmail.com> @date 2020-06 @see https://osprogramadores.com/desafios/d05/ */ #include <boost/iostreams/device/mapped_file.hpp> #include <fstream> #include <iomanip> #include <iostream> #include <map> #include <memory> #include <set> #include <sstream> #include <string> #include <thread> #include <unordered_map> #include <vector> using namespace std; typedef long long int LongInteger; struct Chunk { const char* begin; const char* end; }; struct Employee { Chunk name; Chunk surname; int salary; Chunk area; bool surname_max = false; }; struct Area { string name; vector<Employee> area_max; vector<Employee> area_min; double avg_salary = 0.0; LongInteger total_employees = 0; LongInteger total_salaries = 0; }; struct ParseChunk { shared_ptr<thread> thread_chunk; Chunk data_chunk; map<string, Area> areas; unordered_map<string, vector<Employee>> surname_max; }; template<typename Cmp> inline bool compare_exchange_employees(vector<const Area*>& lst_change, const Area& area_cmp, Cmp cmp) { if (lst_change.size()) { if (cmp(area_cmp.total_employees, (*lst_change.begin())->total_employees)) lst_change = vector<const Area*>{ &area_cmp }; else if (area_cmp.total_employees == (*lst_change.begin())->total_employees) lst_change.push_back(&area_cmp); return true; } else lst_change = vector<const Area*>{ &area_cmp }; return false; } template<typename Cmp> inline bool compare_exchange_salary(vector<Employee>& lst_change, const Employee& employee, Cmp cmp) { if (lst_change.size()) { if (cmp(employee.salary, lst_change.begin()->salary)) lst_change = vector<Employee>{ employee }; else if (employee.salary == lst_change.begin()->salary) lst_change.push_back(employee); return true; } else lst_change = vector<Employee>{ employee }; return false; } template<typename Cmp> inline bool compare_exchange_salary(vector<Employee>& lst_change, const vector<Employee>& lst_cmp, Cmp cmp) { if (lst_change.size()) { if (lst_cmp.size()) { if (cmp(lst_cmp.begin()->salary, lst_change.begin()->salary)) lst_change = lst_cmp; else if (lst_cmp.begin()->salary == lst_change.begin()->salary) lst_change.insert(lst_change.begin(), lst_cmp.begin(), lst_cmp.end()); return true; } } else lst_change = lst_cmp; return false; } void parse(ParseChunk* data) { Employee employee; string surname; string area_name; Area* area; vector<Employee>* employees; auto mystrchr = [&](const char* str, char ch) { while (*str && *str != ch) ++str; return str; }; auto myatoi = [&](const char* beg, const char* end) { int ret = 0; while (beg < end) { char c = *beg++; if (c == '.') continue; ret = ret * 10 + c - '0'; } return ret; }; const char* curr = mystrchr(data->data_chunk.begin, '"'); const char* end; while (curr && curr < data->data_chunk.end) { switch (curr[1]) { case 'i': // employee curr += 2; curr = mystrchr(curr + 1, ','); curr += 6; curr = mystrchr(mystrchr(curr + 1, ':') + 1, '"') + 1; end = mystrchr(curr, '"'); employee.name = Chunk{ curr, end }; curr = end + 11; curr = mystrchr(mystrchr(curr + 1, ':') + 1, '"') + 1; end = mystrchr(curr, '"'); employee.surname = Chunk{ curr, end }; curr = end + 9; curr = mystrchr(curr + 1, ':') + 1; end = mystrchr(curr, '.') + 3; employee.salary = myatoi(curr, end); curr = end + 6; curr = mystrchr(mystrchr(curr + 1, ':') + 1, '"') + 1; end = mystrchr(curr, '"'); employee.area = Chunk{ curr, end }; curr = end + 1; curr = mystrchr(curr, '}'); area_name = string(employee.area.begin, employee.area.end); area = &data->areas[area_name]; compare_exchange_salary(area->area_max, employee, greater<LongInteger>()); compare_exchange_salary(area->area_min, employee, less<LongInteger>()); surname = string(employee.surname.begin, employee.surname.end); employees = &data->surname_max[surname]; compare_exchange_salary(*employees, employee, greater<LongInteger>()); ++area->total_employees; area->total_salaries += employee.salary; break; case 'c': // area curr += 6; curr = mystrchr(mystrchr(curr + 1, ':') + 1, '"') + 1; end = mystrchr(curr, '"'); area_name = string(curr, end); curr = end + 6; curr = mystrchr(mystrchr(curr + 1, ':') + 1, '"') + 1; end = mystrchr(curr, '"'); data->areas[area_name].name = string(curr, end); curr = end + 1; curr = mystrchr(curr, '}'); break; } curr = mystrchr(curr + 1, '"'); } } int main(int argc, char* argv[]) { if (argc == 2) { const char* fileName = argv[1]; boost::iostreams::mapped_file_source fileMap; fileMap.open(fileName); if (fileMap.is_open()) { const char* data = fileMap.data(); size_t cores = std::thread::hardware_concurrency(); size_t chunkSize = fileMap.size() / cores; vector<ParseChunk> chunks(cores); for( size_t i = 0; i < cores; ++i ) { const char* begin = data + (i * chunkSize); const char* end = data + ( (i+1) * chunkSize); chunks[i].data_chunk = Chunk{ begin, end }; chunks[i].thread_chunk = make_shared<thread>(parse, &chunks[i]); } ParseChunk total; Area global; for (const auto& chunk : chunks) { chunk.thread_chunk->join(); for (const auto& area : chunk.areas) { Area& total_area = total.areas[area.first]; total_area.total_employees += area.second.total_employees; total_area.total_salaries += area.second.total_salaries; compare_exchange_salary(total_area.area_max, area.second.area_max, greater<LongInteger>()); compare_exchange_salary(total_area.area_min, area.second.area_min, less<LongInteger>()); if( area.second.name.size() ) total_area.name = area.second.name; } for (const auto& surname_max : chunk.surname_max ) { const string& surname = surname_max.first; vector<Employee>& total_surname = total.surname_max[surname]; bool exchange = compare_exchange_salary(total_surname, surname_max.second, greater<LongInteger>()); total_surname.begin()->surname_max = exchange; } } vector<const Area*> most_employees, least_employees; for (auto& area : total.areas) { if (area.second.total_employees) { area.second.avg_salary = ( double(area.second.total_salaries) / 100.0 ) / double(area.second.total_employees); global.total_employees += area.second.total_employees; global.total_salaries += area.second.total_salaries; compare_exchange_salary(global.area_max, area.second.area_max, greater<LongInteger>()); compare_exchange_salary(global.area_min, area.second.area_min, less<LongInteger>()); compare_exchange_employees(most_employees, area.second, greater<LongInteger>()); compare_exchange_employees(least_employees, area.second, less<LongInteger>()); } } global.avg_salary = ( double(global.total_salaries) / 100.0 ) / double(global.total_employees); auto out_salary = [](LongInteger salary) -> string { ostringstream os; os << (salary / 100) << '.' << setfill('0') << setw(2) << (salary % 100); return os.str(); }; for (const auto& emp : global.area_max) cout << "global_max|" << string(emp.name.begin, emp.name.end) << ' ' << string(emp.surname.begin, emp.surname.end) << '|' << out_salary(emp.salary) << '\n'; for (const auto& emp : global.area_min) cout << "global_min|" << string(emp.name.begin, emp.name.end) << ' ' << string(emp.surname.begin, emp.surname.end) << '|' << out_salary(emp.salary) << '\n'; cout << "global_avg|" << fixed << setprecision(2) << global.avg_salary << '\n'; for (const auto& area : total.areas) { for (const auto& emp : area.second.area_max) cout << "area_max|" << area.second.name << '|' << string(emp.name.begin, emp.name.end) << ' ' << string(emp.surname.begin, emp.surname.end) << '|' << out_salary(emp.salary) << '\n'; for (const auto& emp : area.second.area_min) cout << "area_min|" << area.second.name << '|' << string(emp.name.begin, emp.name.end) << ' ' << string(emp.surname.begin, emp.surname.end) << '|' << out_salary(emp.salary) << '\n'; if( area.second.total_employees ) cout << "area_avg|" << area.second.name << '|' << fixed << setprecision(2) << area.second.avg_salary << '\n'; } for (const auto& emp : most_employees) cout << "most_employees|" << emp->name << '|' << emp->total_employees << '\n'; for (const auto& emp : least_employees) cout << "least_employees|" << emp->name << '|' << emp->total_employees << '\n'; for (const auto& emps : total.surname_max) { if (emps.second.begin()->surname_max || emps.second.size() > 1) { string surname = string(emps.second.begin()->surname.begin, emps.second.begin()->surname.end); for (const auto& emp : emps.second) cout << "last_name_max|" << surname << '|' << string(emp.name.begin, emp.name.end) << ' ' << surname << '|' << out_salary(emp.salary) << '\n'; } } fileMap.close(); } } else cout << "How to use: program <input-file>\n"; }
# Download PDB symbols
Caloni, 2025-04-30 <code> [up] [copy]#include <windows.h> #include <dbghelp.h> #include <algorithm> #include <cstdint> #include <filesystem> #include <iostream> #include <string> #include <vector> #pragma comment(lib, "dbghelp.lib") namespace fs = std::filesystem; int main() { const fs::path RootPath = fs::path("resources"); auto isBinary = [](const fs::path& path) { return path.extension() == ".exe" || path.extension() == ".dll" || path.extension() == ".sys"; }; ::SymInitialize(::GetCurrentProcess(), NULL, FALSE); try { for (const auto& entry : fs::directory_iterator(RootPath)) { std::cout << entry.path().string() << std::endl; try { if (entry.is_regular_file() && isBinary(entry.path())) { auto imageName = entry.path().string(); SYMSRV_INDEX_INFO imageFileInfo = { sizeof(imageFileInfo) }; ::SymSrvGetFileIndexInfo(imageName.c_str(), &imageFileInfo, 0); char downloadedImagePath[MAX_PATH + 1] = { 0 }; if (::SymFindFileInPath(GetCurrentProcess(), NULL, imageName.c_str(), &imageFileInfo.timestamp, imageFileInfo.size, 0, SSRVOPT_DWORDPTR, downloadedImagePath, nullptr, nullptr)) { std::cout << "Image file downloaded to " << downloadedImagePath << std::endl; } char downloadedPdbPath[MAX_PATH + 1] = { 0 }; if (::SymFindFileInPath(GetCurrentProcess(), NULL, imageFileInfo.pdbfile, &imageFileInfo.guid, imageFileInfo.age, 0, SSRVOPT_GUIDPTR, downloadedPdbPath, nullptr, nullptr)) { std::cout << "PDB file downloaded to " << downloadedPdbPath << std::endl; } } } catch (std::exception& e) { std::cerr << entry.path().string() << ": " << e.what() << std::endl; } } } catch (std::filesystem::filesystem_error& e) { std::cout << "No resources directory found; nothing to do here: " << e.what(); } ::SymCleanup(::GetCurrentProcess()); return 0; }
# Hook using detour
Caloni, 2025-04-30 <code> [up] [copy]#include <detours.h> #include <windows.h> using namespace std; decltype(SendMessageA)* Orig_SendMessageA = ::SendMessageA; decltype(SendMessageW)* Orig_SendMessageW = ::SendMessageW; LRESULT WINAPI Hook_SendMessageA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI Hook_SendMessageW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); struct Hook { PVOID& original; PVOID hook; }; static Hook g_installedHooks[] = { { (PVOID&)Orig_SendMessageA, Hook_SendMessageA }, { (PVOID&)Orig_SendMessageW, Hook_SendMessageW }, }; LRESULT WINAPI Hook_SendMessageA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { LRESULT l = Orig_SendMessageA(hWnd, Msg, wParam, lParam); printf("Hook_SendMessageA %x %d", hWnd, Msg); return l; } LRESULT WINAPI Hook_SendMessageW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { LRESULT l = Orig_SendMessageW(hWnd, Msg, wParam, lParam); printf("Hook_SendMessageW %x %d", hWnd, Msg); return l; } static void InstallHooks() { DetourRestoreAfterWith(); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); for (auto& hook : g_installedHooks) { DetourAttach(&(PVOID&)hook.original, hook.hook); } DetourTransactionCommit(); } static void UninstallHooks() { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); for (auto& hook : g_installedHooks) { DetourDetach(&hook.original, hook.hook); } DetourTransactionCommit(); } BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { if (DetourIsHelperProcess()) { return TRUE; } if (ul_reason_for_call == DLL_PROCESS_ATTACH) { //MessageBoxA(NULL, "Ready to install hooks", "Dll1", 0); LogFormat("Installing hooks"); InstallHooks(); LogFormat("Hooks installed"); } else if (ul_reason_for_call == DLL_PROCESS_DETACH) { LogFormat("Uninstalling hooks"); UninstallHooks(); LogFormat("Hooks uninstalled"); } return TRUE; }
# Subir escadas
Caloni, 2025-04-30 <body> <essays [up] [copy]Subir escadas é o exercício mais simples possível que mantém em forma as partes mais importantes do seu corpo no longo prazo: pernas e coração. Com as pernas em forma você deve conseguir chegar em uma idade avançada podendo se locomover. Com o músculo do coração em dia você deve conseguir suportar bombear sangue com eficiência e sem sobrecarga. Subir escadas é simples porque basta achar uma escada e começar a subir. O ritmo é definido pela sua capacidade física do momento. Pode ser que um dia suba mais rápido, outro dia mais lento. Você deve subir pelo tempo que achar possível para você, sem comprometer o corpo nem a agenda. Você pode alternar o ritmo ao prestar atenção ao coração batendo mais ou menos, a tontura vindo ou as pernas se cansando. Você pode forçar o corpo de vez em quando a subir o platô ouvindo podcast ou música enquanto faz o exercício, conscientemente ignorando alguns avisos do corpo para se lançar alguns degraus a mais. Você não precisa mensurar nada fora do seu corpo. O tempo gasto não importa. O ritmo não importa. A geolocalização não importa. Se mover importa. Portanto se mova e quando achar melhor pare. Repita de vez em quando. Não precisa ser todos os dias. Não exija disciplina de você. Apenas constância. E isso irá adicionar um hábito saudável e regulável por décadas a fio em seu itinerário de atividades. Irá também aos poucos te inspirar a fazer outras atividades, como caminhadas ao ar livre ou até algo mais ousado. Quem definirá serão seus gostos e sua vontade, moldada pelo pequeno degrau inicial que você ousou subir.
# Journaling and coding
Caloni, 2025-04-30 <essays> [up] [copy]Codar e blogar são tarefas equivalentes. Quando digo blogar estou me referindo a escrever em geral. Textos são apenas linguagens de programação naturais que usam símbolos que seres humanos conseguem decodificar. E como somos máquinas de Turing completas, nossas leituras do mundo, textuais ou outros, interferem nas nossas saídas, e assim por diante. Escrever textos em linguagem natural ou linguagens de programação são essencialmente atividades que codificam símbolos em uma certa disposição, modificam símbolos obedecendo determinadas regras da chamada gramática. Quando estou escrevendo código ou um texto para o blogue a atividade deveria seguir exatamente os mesmos passos, assim como a montagem do histórico, o que significa documentar as mudanças no controle de fonte.