-
-
Notifications
You must be signed in to change notification settings - Fork 59
/
git & Linux cmds, help, tips & tricks - Gabriel.txt
7406 lines (6393 loc) · 478 KB
/
git & Linux cmds, help, tips & tricks - Gabriel.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
Gabriel Staples
This file is part of eRCaGuy_dotfiles: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
Video of HOW IT FEELS TO *NOT* BE DOING CONTROLS OR MOTION PLANNING, OR SENSORS OR ACTUATORS IN MY DAY-JOB:
https://www.linkedin.com/feed/update/urn:li:activity:6964107799882575873/
I'd rather do that kind of work--it would pump up my spirits. Need that kind of work done? Hire me.
MY RESUME: https://drive.google.com/file/d/1qgDBc1nYYgqGs79IVOfYlSQ7wInOENkN/view?usp=sharing
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
HOW TO FUZZY-SEARCH THIS FILE:
---
cat "path/to/eRCaGuy_dotfiles/git & Linux cmds, help, tips & tricks - Gabriel.txt" | fzf -m --reverse
[GOOD] Fuzzy search this file withOUT showing line numbers.
See my comment: https://github.com/junegunn/fzf/issues/1034#issuecomment-1054558594
grep -n '' "path/to/eRCaGuy_dotfiles/git & Linux cmds, help, tips & tricks - Gabriel.txt" | fzf -m --reverse
[BETTER] Fuzzy search this file WITH showing line numbers!
See my comment: https://github.com/junegunn/fzf/issues/1034#issuecomment-1054558594
gs_fzf_git_and_linux_cmds_doc
<========= FUZZY SEARCH THIS DOCUMENT! =========
[BEST] Same as above, but use my bash function which is defined in ".eRCaGuy_dotfiles/home/.bash_aliases" instead!
====================================================================================================
= Mentorship: =
====================================================================================================
[how to be a good mentor]
References:
1. *****+++ Primary reference: https://hbr.org/2019/08/great-mentors-focus-on-the-whole-person-not-just-their-career
"Great Mentors Focus on the Whole Person, Not Just Their Career"
https://hbr.org/2019/08/great-mentors-focus-on-the-whole-person-not-just-their-career
Note: other types of knowledge-sharing and guiding include:
- coaching (ex: training in soft skills or job changes)
- skill-building (ex: teaching C++, electrical engineering, or controls)
- performance feedback (ex: a manager providing work-related performance feedback to someone under them on their team)
> Share your stories. When I meet with a younger person for the first time, I say: “Tell me your story. Start at the beginning and take your time — 20 or 30 minutes. I may ask a few questions, and everything you say will be confidential between us. Then, when you’re finished, I’ll tell you my story if you want me to.” (They always do.) This simple exercise can transform the trajectory of a mentoring relationship because it shows that you’re truly interested in understanding your mentee and his or her journey, not just in dispensing professional advice. It gives you knowledge of the person’s past which enables you to make more probing inquiries over time. When I tell my story, I make sure to describe one or two of the difficult chapters in both my career and personal life, including my marriage. This signals that all aspects of our lives are on the table.
> Ask great questions. Effective mentors develop a storehouse of probing questions on any number of subjects. Examples include:
>
> 1. What keeps you up at night?
> 1. Can you see yourself being stimulated and fulfilled on your current career path for the next five years?
> 1. What do you do to “reboot” so that the busyness and tech overload in your life does not result in burnout?
> 1. Who has been most influential in your life?
> 1. What did you love doing in high school?
> 1. What would you have done differently in your life if you had the chance?
> 1. On a scale of 1 to 10, how would you rate your marriage/romantic relationship right now?
> 1. How was your relationship with your parents?
> 1. Were you raised in a particular faith or religious tradition?
"If you must make an ethics decision that potentially affects keeping your job, keeping your client, or keeping your professional license, you should decide on the path that keeps your license. You can always get another employer or another client, but you rarely can get another license."
- VectorSolutions, "Ethics for Professionals" training, Conclusion slide/section.
<=====
- "If your obligation to your employer or client conflicts with your professional obligation or ethics, you should 'have such objectionable conditions corrected, or resign.'"
- "If you know a professional that behaves unethically, you should 'avoid association with that professional'."
- VectorSolutions, "Ethics for Professionals" training
----------------
Words of wisdom:
----------------
"When men carry bound energy, it makes women [or people in general] feel unsafe."
- Raj Narayanan - https://www.linkedin.com/in/raj920/
GS Context: stuffing down energy like anger, resentment, pain, hurt, etc., can lead to volcano-like explosions, negativity, negative energy or sentiment, etc. This is what we call "bound energy". If we just get with our emotions every day, instead, and experience them at no one and nothing, we can instead free that energy and be a safe space for others.
"When are things going to turn around?
Answer: When you're fully there. That's the only answer I can give you.
When you're committed to being there, and you're fully there."
- Raj Narayanan - https://www.linkedin.com/in/raj920/
GS: in other words, when we have done the work and have done **our part**, **then** we will be ready to embrace the positive changes that are coming.
1. *****+ "Numbers are important, but don’t let them define your choices. Don’t use money to cut back on things you love just because they're "expensive." Use money to actualize your vision for how you want to live your life."
- Dexter Zhuang (https://www.linkedin.com/in/dexter-zhuang/)
https://www.linkedin.com/posts/dexter-zhuang_in-2019-i-left-my-cushy-san-francisco-tech-activity-7061146444270858241-OS0M/
[Practice "defensive employment"]
1. Don't go 110%!: https://www.tiktok.com/@phong.thieu/video/7131489984686640390?is_from_webapp=v1&item_id=7131489984686640390
1. Let it burn! 🔥🔥: https://www.tiktok.com/@phong.thieu/video/7138809958451121414?is_copy_url=1&is_from_webapp=v1&item_id=7138809958451121414
1. If deadlines truly are unreachable, they should burn 🔥. It's the only way leadership ever realizes there's a problem, you know?
1. *****+ Part of the ebb and flow of life and "work/life balance" or "work/life harmony" is that sometimes you must spend extra time on your family and it will affect your bonus, and sometimes you can spend extra time at work and it will help you get promoted in your current job or find a new job.
keywords: gabriel staples elusive work-life balance, no!: it is a work-life **harmony**, with give and take, ebb and flow, sometimes giving more to one role in your life than another, and alternating as necessary so that you can do your best work and be mos-productive in each role in its due time:
See also:
1. Work-life harmony, by Nicole Malachowski: https://www.linkedin.com/feed/update/urn:li:ugcPost:6942500854797152256/?commentUrn=urn%3Ali%3Acomment%3A%28ugcPost%3A6942500854797152256%2C6943330228509315072%29
2. https://www.linkedin.com/posts/gabriel-staples_inspiration-work-lifebalance-activity-7003243118720425984-g7ko?utm_source=share&utm_medium=member_desktop
3. ***** [my LinkedIn post with this very content] https://www.linkedin.com/feed/update/urn:li:ugcPost:7003891808833351680/
Is there an elusive work-life balance? No!: it is a work-life **harmony**, with give and take, ebb and flow, sometimes giving more to one role in your life than another, and alternating as necessary so that you can do your best work and be most-productive in each role in its due time.
Ex: let's say you spend 2 months of intense house hunting, followed by a huge family move to move into the new house, get settled there, and fix it up. Perhaps you have maintenance people in the home many days, and that distracts from work and requires your attention. Perhaps you have a difficult closing process and must take an extra 10 days off of work to work with the lender, provide documentation, do home inspections, or coordinate with the builder, etc. As a result of these things, you may have to "partially meet" expectations for that season of your employment, perhaps even losing a portion of or all of your annual bonus. 💸$$💸 Instead of thinking, "I failed! I am not meeting expectations", the thought of which drags you down into despair, think to yourself: "I **SUCCEEDED** and **AM SUCCEEDING**!" "I manged to get my family into a new home while keeping my job, despite all these difficulties. I have **succeeded**!" Then, get back to work.
As someone who has traditionally flat-out neglected my family (to their and my severe detriment--and generally with it _still_ not being enough for what my work/employer wants anyway) for fear of not succeeding at work, I have begun to realize that "work-life balance" (or "work-life harmony", as some people call it [see link 1 above]) doesn't mean "trying to meet family expectations *and* work expectations all of the time, no matter what". Rather, it means: "sometimes meeting work expectations, and sometimes meeting family expectations, according to the season of life you are in and the individual circumstances at play." Sometimes, you must spend very little time with your family for 5+ years to get through a grueling school program or to grind through a really hard time in life where you are working one job while building skills for another. And, you do this "work" ultimately *for your family*. In the end, it benefits both, but in the moment, it feels like losing your family or losing your work. And, sometimes you must reduce your work output significantly so you can get your family into the house you've been working for for the last 25 years (or to help out with medical needs, or to do some other really important thing), even though that reduced output may mean your employer removes your bonus and tells you you are failing. If you have done all you can do and kept your job or found another one, you are *not* failing. You are **succeeding**! You have discovered that your work at home or for others is important and is not replaced in importance by your work for your employer.
In other words: ***you have found work-life balance!***
1. The **85% rule:** to reach your full potential, aim for 85%, not 100%: https://www.linkedin.com/posts/danfounder_the-85-rule-ugcPost-7005885256721461250-wu83?utm_source=share&utm_medium=member_desktop
- 100% just feels too overwhelming, and will actually cause you to *decrease* performance. When you strive for 85% it leaves room to relax and enjoy the process and get into the flow, rather than just feeling stressed all the time.
- Here are my words on it: [my own post] https://www.linkedin.com/feed/update/urn:li:activity:7005947220453720065/
1. @Alex Nguyen on "What I wish I knew hopping companies": https://www.linkedin.com/posts/alxngu_alexcancode-career-coding-activity-7005961425647009793-71UI?utm_source=share&utm_medium=member_desktop
1. “Children are not distraction from more important work they are the most important work” -C.S. Lewis
From LinkedIn post by @Sanjay Pendharkar: https://www.linkedin.com/feed/update/urn:li:activity:7006792087178260481?utm_source=share&utm_medium=member_desktop
====================================================================================================
= Fun facts: =
====================================================================================================
A collapsing electromagnetic field when you rapidly turn off a switch to DC power causes an inductance-induced voltage spike akin to a water hammer in your pipes causing an inertia-induced pressure spike when you rapidly turn off the water.
- Gabriel Staples, 13 June 2024
====================================================================================================
= Quotes: =
====================================================================================================
"Anyone can take anything from you, except your honor and integrity. Only *you* can give that away."
- Matthew Snider, US Army Ranger: "A" Company 2nd Platoon 3/75 Ranger Battalion Special Operations Command (SOCOM), quoting his grand-dad, 13 June 2024
"Yes is yes. Maybe is yes. And a no is just a delayed yes."
<=== a perspective I need to have more in life, to keep me calm and help me carry on.
- Friend of Elon Musk, at 36:10 in "Elon Musk: The Real Life Iron Man", a video documentary on Tubi.
GS notes: [How to have an optimistic perspective to drive you to keep trying in business even when it seems impossible]
"Entrepreneurs have a phenomenal bounce back factor. They *expect* to fail sometimes."
Another quote from a different person (who seemed reputable in my view), at 36:46 in "Elon Musk: The Real Life Iron Man", a video documentary on Tubi.
"Working hard for something we don't care about is called stress. Working hard for something we love is called passion."
- Simon Sinek, on Linkedin
https://www.linkedin.com/in/simonsinek/
https://www.goodreads.com/quotes/7697100-working-hard-for-something-we-don-t-care-about-is-called
"Don't apply for a specific job. Find a company you want to work for and get in any way you can."
- Max Landesman
Slide 5 of 9 shared by Austin Belcak here: https://www.linkedin.com/posts/abelcak_7-best-pieces-of-career-advice-ugcPost-7027298563168591872-82La?utm_source=share&utm_medium=member_desktop
"Set your own boundaries for work/life balance. No one else will do that for you."
- Jess Almlie
Slide 7 of 9 shared by Austin Belcak here: https://www.linkedin.com/posts/abelcak_7-best-pieces-of-career-advice-ugcPost-7027298563168591872-82La?utm_source=share&utm_medium=member_desktop
"I believe that creating a culture of valuing people doesn't just make them *feel* better to be on your team, it makes them work harder and *perform* better with greater *success* on your team. If you as a manager do this, then instead of a win/lose relationship in the *short term* (making them work extra now [they lose] for greater immediate productivity [you win]), and a lose/lose relationship in the *long term* (they leave your team because they are burned out and don't want to work for you anymore), you'll end up with a win/win relationship in the mid to long term (they are happy, less stressed, and more-productive, and get more work done). Have the vision. Choose the win/win. Be a hero. Hire heroes."
- Gabriel Staples
See the full context in my post here, including the post I re-shared, by Alex Nguyen. It's about being a good manager who values people and treats them well and has a long-term win/win vision in mind:
https://www.linkedin.com/posts/gabriel-staples_alexcancode-career-engineer-activity-7029863104406593536-JtYI?utm_source=share&utm_medium=member_desktop
"Just keep trying. Care enough to make it right, and it will really separate you from a staggering amount of more-talented wood-workers." [GS: or engineers, software developers, or whatever it is you do].
- Blacktail Studio owner (Cameron Banderson, I think, based on his [Ebay auctioneer name](https://www.ebay.com/itm/195320349148), at 22:50 in this YouTube video here: https://www.youtube.com/watch?v=8wYDq9F8J7M&t=1370s
GS notes: I think this applies to any talent or profession. See my comment here: https://www.youtube.com/watch?v=8wYDq9F8J7M&lc=UgzAaYEFmsJd5-K_bOd4AaABAg
"Computer Science: solving today's problems, tomorrow."
- One of the many random quotes displayed on the Eclipse IDE splash screen during startup when you have the "Darkest Dark Theme with DevStyle 2022.6.13a" plugin installed
"Whatever the cause of such strife may be, simply ruminating on the issue — or deliberately engaging in conflict avoidance tactics (i.e. people-pleasing), will do nothing to resolve said contention. The fact of the matter is, confrontation is necessary, and if done properly can dramatically increase the quality of our lives — in addition to that of our relationships."
- A.J. Deveaux, Why Confrontation is Good, How to properly handle conflict, medium.com (https://medium.com/swlh/why-confrontation-is-good-20aa32a69dd1), 23 May 2019.
- On confrontation, and how to handle conflicts [Applies to *most* people and situations, NOT all. Some people you *do* need to avoid and not confront, esp. if they are manipulative and/or continually contemptuous towards you, or if they have antisocial personality disorder (ASPD: https://www.webmd.com/mental-health/antisocial-personality-disorder-overview)].
"Programming isn't what you know; it's what you can figure out." <===
- One of the many random quotes displayed on the Eclipse IDE splash screen during startup when you have the "Darkest Dark Theme with DevStyle 2002.5.5" plugin installed; seen 13 Apr. 2022
- GS: in other words: really expert and skilled programmers do NOT know how to do everything! Rather, they simply know **how to figure it out**. They know that to solve the problem, they will have to:
1. Identify the problem and the skills they need to solve it.
2. Identify which skills they are lacking.
3. Find resources and teach themselves these new skills, documenting as they go so they can A) refer to their notes later, and B) share them with others to help others learn too.
4. Use the new skills to solve the problem!
For a task which takes 4 days to "just do" if you already know how to do it, this total process might take:
1. 2 days, spread throughout the project ["just-do-it"_time x 0.5]
2. continuously being done
3. 8~12 days ["just-do-it"_time x 2~3]
4. 4 days ["just-do-it"_time]
Total: 14~18 coding work days.
Since there are 10 work days per 2-week sprint, a standard 0.6 workload to account for meetings and fluff leaves you with 10x0.6 = 6 coding work days per sprint. So, 14 coding work days is 14/6 = **2.33 sprints** ~ 18/6 = **3 sprints**.
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv TIME ESTIMATION SKILLS vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
==> TIME-ESTIMATION SKILLS: a "4-day" task (meaning: 4 days if you know **exactly** how to do it) which you have never done yourself should take you **2~3 sprints**, for a total of 14~18 head-down coding work days! <==== TIME ESTIMATION SKILLS ====
- Looking back at my work and time estimates, this seems very accurate, especially when factoring in writing unit tests, doing quick bench testing, and the code review process, as well as other unfamiliarities which pop up during the process, such as the build system or new syntax or libraries you aren't familiar with.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
"The best code is the 'done' code. (Meaning: it is functional [basic features] and works [runs/accomplishes the need])."
- Gabriel Staples, 24 Jan. 2021
> Being in debt is hard. Being financially disciplined is hard. Choose your hard.
> Communication is hard. Not communicating is hard. Choose your hard.
> Obesity is hard. Being fit is hard. Choose your hard.
> Marriage is hard. Divorce is hard. Choose your hard.
> Life is rarely easy. It will be hard. But we can choose our hard.
- Swish Goswami, ~24 Dec. 2020 [on LinkedIn](https://www.linkedin.com/posts/swishgoswami_being-in-debt-is-hard-being-financially-activity-6747804403127910400-Clwh)
"If you love it, you'll teach yourself. If you don't love it, others teach you."
- Yukitaka Yamaguchi, the "Tuna King", Youtube video: "The Tuna King Reigns at Tsukiji Fish Market — Omakase Japan", [11:33](https://youtu.be/trbl4RNgKO0?t=693)
"I have a great love for programming, so I taught myself."
- Gabriel Staples, 18 Dec. 2020
"It's better to be done well and on time, than perfect and late."
- Gabriel Staples, ~2008, while studying at the US Air Force Academy and trying to figure out how to balance time
Or, otherwise stated:
"Done well and on time is better than perfect and never."
- Gabriel Staples--one of my main maxims. I learned this through my experiences at the US Air Force Academy where we were pressured into situations intentionally (primarily academic situations in our university studies, but also in other training environments and settings) where there literally wasn't time for the perfect answer--as happens frequently in war. So, if you're a struggling perfectionist, just get it done well enough and be done!
"Done is good enough."
- Gabriel Staples (inspired by a conversation with Anton Scherbakov), 8 Dec. 2020; a variation to ["Done is better than perfect."](https://lifehacker.com/done-is-better-than-perfect-5870379).
"Document what you know when you know it."
- [Great advice that I truly take to heart!]
- One of the many random quotes displayed on the Eclipse IDE splash screen during startup when you have the "Darkest Dark Theme with DevStyle 2002.5.5" plugin installed
"I understand crossing your fingers is a form of debugging. If it doesn't pass, cross your fingers and try again."
- said nobody ever
(by Gabriel Staples, 25 June 2020)
"You are making progress if each mistake is a new one."
- One of the many random quotes displayed on the Eclipse IDE splash screen during startup when you have the "Darkest Dark Theme with DevStyle 2002.5.5" plugin installed
"Programming isn't what you know; it's what you can figure out." <=====
- One of the many random quotes displayed on the Eclipse IDE splash screen during startup when you have the "Darkest Dark Theme with DevStyle 2002.5.5" plugin installed
"Cost of copying code from Stack Overflow: $1. Cost of knowing which code to copy from Stack Overflow: $100k~$300k/year."
- This is my rewording of a quote from Jessica Su, CS PhD student at Stanford (see: https://www.linkedin.com/posts/stevenouri_datascience-machinelearning-programming-activity-6696689805528571904-BIxM).
Me: "I am a documentation expert." Boss: "What about diagramming?" Me: "Oh...(foot in mouth)." [I'm great at documentation, just not drawing diagrams to demonstrate designs.]
New assertion: Me: "I am a foot-in-mouth expert." Boss: "Yep."
That should be a comic.
"There are two ways to code bug-free; only the third one works."
- One of the many random quotes displayed on the Eclipse IDE splash screen during startup when you have the "Darkest Dark Theme with DevStyle 2002.5.5" plugin installed
"Confusion and clutter are the failure of design, not the attributes of information."
- Edward Tufte
- I first saw this posted on Adafruit.com's order checkout page, here, near the bottom-right: https://www.adafruit.com/index.php?main_page=checkout_success
Keep refreshing the page for more quotes each time!
"The only valid measurement of code quality: WTFs/minute."
- Robert C. Martin
Where I saw it: https://stackoverflow.com/users/583833/borgleader
- *****My thoughts: this is actually a pretty insightful. I have VERY OFTEN looked at code and thought to myself: "What the heck does this mean!?" "Why are they doing that!?" etc. Apparently, I am not alone, which is good to know. I wasn't sure if it was just me, as I frequently wonder if most other programmers are just much smarter than me and I'm the only one "not getting it". This quote seems to indicate that is not the case. I have also noticed that the less often I have to wonder what the heck is going on when reading someone else's code, the better and higher-quality I consider that code to be, so I can affirm the validity of this quote!
"Any technology distinguishable from magic is insufficiently advanced."
- One of the many random quotes displayed on the Eclipse IDE splash screen during startup when you have the "Darkest Dark Theme with DevStyle 2002.5.5" plugin installed
- This is super funny! 😂 Actually made me laugh out-loud since they're making a joke of the other phrase similar to it.
"Maybe it's overconfidence, but I have a mentality that another human figured it out, so I can, too, even if maybe it takes me longer."
- Sam Zeloof, home-made garage IC chip designer and fabricator, doing it in his parents' garage since high school
- https://arstechnica.com/information-technology/2022/01/this-22-year-old-builds-chips-in-his-parents-garage/
..."The reason for doing it was honestly because I thought it would be funny,"" he says. "I wanted to make a statement that we should be more careful when we hear that something's impossible."
====================================================================================================
= My Thoughts on C++: =
====================================================================================================
"Every chance you get, eliminate a template. If you can write _clean_ code without using a template, do so. Simplicity is better."
- Gabriel Staples, 22 Oct. 2020
My jab against C++ developers [a little "tongue in cheek", but also true]:
- A C developer prides himself in using a programming language to produce a desired outcome.
- A C++ developer prides himself in producing the world's most complicated language **as** the desired outcome.
C++'s syntax alone is, unfortunately, a never-ending story [C++'s syntax is nuts!]:
"C++ is completely nuts."
- Gabriel Staples, 15 May 2020. See here: https://stackoverflow.com/questions/47002799/what-does-the-ampersand-at-the-end-of-member-function-signature-mean/47003980?noredirect=1#comment109357350_47003980
"After having used C++ since the late 80's, I still feel the same way [that "C++ is completely nuts"]. As more and more corner-case niceties are added to the endless string of value-types, deductions, ranges, views, chronos, etc.. it feels a lot more like Python than it does C++. Don't get me wrong, I'm not saying additional features and capabilities are a bad thing, there is someone out there that will use the feature, but to say you can remain current without continually re-learning C++ is just that -- nuts. The language seems to have fragmented into an ever increasing number of specialized subcomponents."
- David C. Rankin, 3 Sept. 2023, experienced software developer, engineer, lawyer, and open-source advocate. See here: https://stackoverflow.com/questions/47002799/what-does-the-ampersand-at-the-end-of-member-function-signature-mean/47003980?noredirect=1#comment135796477_47003980
I frequently tell people:
> If the syntax of C is like Spanish, the syntax of C++ is like Spanish + English + French + Italian + Portuguese + German.
>
> And the problem is that even if you write the most perfect and beautiful Spanish in C++, the Frenchers will hate it. And even if you write the most beautiful and perfect French in C++, the Germans will hate it.
>
> That's the problem with C++.
~ Gabriel Staples
Written down 28 Sept. 2022, even though I've been telling people this for a couple years now.
23 Oct. 2020:
Note: the above quote above (and repeated just below) about eliminating templates does NOT mean: "don't use templates". If you have a function that truly needs to work for many data types, that is a good use for a template, so _use a template!_ BUT, if you can simply reduce your plethora of types and go back to a little more simplicity, something more like _modern_ C (1), between old-school C and modern "go-nuts" C++, you are better off. It seems to me the simplicity will pay off dividends in the long run, enabling you ultimately to have fewer hurdles for new developers to contribute, faster progress for the whole team, and safer code because it is understandable and more likely to be correct and do what you want it to do.
This is my hypothesis. I am still testing it, but right now, that's what I recommend: "every chance you get, eliminate a template."
(1) For some examples of code I've written where I demonstrate aspects of what I mean when I say "modern C", and/or "simple C++", see here:
1. [my answer] https://stackoverflow.com/questions/3965279/opaque-c-structs-how-should-they-be-declared/54488289#54488289
2. [my answer] https://stackoverflow.com/questions/34196663/stm32-how-to-get-last-reset-status/54728664#54728664
3. [my answer] https://stackoverflow.com/questions/21856025/getting-an-accurate-execution-time-in-c-micro-seconds/49066369#49066369
- NB: this is C++, but this is a **great** illustration of what I mean when I say "simpler types" with fewer templates! Instead of this craziness: `std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count()`, PLEASE just use `uint64_t microseconds` or `uint64_t us` instead!
- See also my comments underneath my answer.
- This is also an **excellent** demonstration of what I mean when I say I aim to "have fewer hurdles for new developers to contribute". The `std::chrono` library is a HUGE hurdle for someone to conquer when moving from C to C++! IT **ALONE** could set back an expert C developer from making strong C++ contributions **FOR _WEEKS_**! I say: "Every chance you get, eliminate a template. If you can write _clean_ code without using a template, do so. Simplicity is better."
17 Sept. 2020:
As compared to C, or even better, "C+" (more on this later), I personally dislike the "hard-core" C++ "type-safety-first" mentality common to modern application-level C++.
But, I'm still forming an opinion, and have much to learn.
As an embedded software developer first, I definitely prefer a more C-like style, which I call "C with classes", or "C+", when programming with the C++ compiler. This consists of using many C styles but with a C++ compiler and with C++ classes, C++ features like default values in function prototypes and structs, function overloading, etc. I think C++ has many wonderful things to offer, but is just too huge. Using only C, on the other hand, is just too redundant and limiting. The C++ compiler has many beautiful and wonderful features which can make programming a true joy, when done in the "C+" style I describe above.
Since I speak multiple languages (English, Spanish, + quite a bit of French, and I read and write Arabic) and have a passion for learning and studying foreign languages and cultures, I frequently make the following analogy to foreign languages:
Imagine **C is Spanish**. It is well-defined, well-scoped, and follows nice, fixed rules and patterns in its syntax. Its syntax follows rules very well, and when there are exceptions to these rules, you can write them out in a list and that's it! Those are the rules, and those are the exceptions to those rules! Done! At the architectural level, many options exist, but a few well-accepted architectures have arisen.
**C++ is Spanish, German, French, English, Italian and Portuguese** all rolled into one. The problem is that if you write perfect Spanish in C++, the (Portuguese + French)ers in C++ will tell you how horrible your code is because it looks like Spanish, even if the Spanish you wrote and compiled with the C++ compiler is perfect, flawless, bug-free, functional C++, **since C++ includes Spanish**. C++ is HUGE. You have many many ways to use C++, and no matter how long you study it, you have never even covered all of its _syntax_, let alone its extensive libraries and multiplicitous architectural options.
In C, architecturally, I am quite familiar with and fond of "object-based C". I have written a thorough example of this architectural style here: https://stackoverflow.com/questions/3965279/opaque-c-structs-how-should-they-be-declared/54488289#54488289. An alternative "object-based C" style exists which allows static memory allocation instead, for your "objects", and I'd probably prefer this more over what's in my answer, but what's in my answer happened to be what I was more familiar with. This "object-based" C style does not prohibit procedural code and functions mixed throughout.
In programming paradigms, I am fond mostly of **procedural** programming, which is a subset of **imperative** programming. Here's what I wrote in a comment [under this answer](https://stackoverflow.com/questions/6295148/what-is-the-opposite-of-oop/6295260#6295260) to the question of, "What is the opposite of OOP? [Object-Oriented Programming]":
> I'd say based on what the asker is after, **procedural** is the opposite of **object-oriented** programming. Procedural is a subset of **imperative**, but more narrowly defined as being imperative + relying on blocks & scope (source: https://en.wikipedia.org/wiki/Procedural_programming#Imperative_programming). With this in mind, in a sense, C (a primarily procedural programming language) is the opposite of C++ (a primarily object-oriented programming language).
So, I prefer **procedural** programming to pure OOP. If taken too far, OOP gets huge, ugly, and utterly obnoxious to use. This contributes to my occasional hatred towards C++, when all I want to use is "C+." C++, for instance, can make better and cleaner and more beautiful **procedural** code than C could ever dream of. Some of the aspects of C++, like function overloading and setting default members in structs, are wonderful to use. Regarding the ugliness of OOP, however, which for some reason is the dominant form of C++ even when it doesn't make any sense for the problem being solved and ends up creating a dozen singleton classes everywhere, Joe Armstrong, creator of Erlang, had the following to say:
> I think the lack of reusability comes in object-oriented languages, not functional languages. Because the problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. **You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.**
> If you have referentially transparent code, if you have pure functions — all the data comes in its input arguments and everything goes out and leave no state behind — it’s incredibly reusable.
(Source: ["Coders at Work" book](https://amzn.to/2LUe3aO), requoted by John D. Cook, PhD, here: https://www.johndcook.com/blog/2011/07/19/you-wanted-banana/)
So, when using the C++ compiler, please, I don't need the whole gorilla holding the banana, and the entire jungle too! Sometimes, simplicity is best. Step back for a moment and consider trying to create something a little less OOP, a little less type-safe (because the extreme complexity of overly-type-safe code can be very dangerous too!), a little more simple and usable and procedural, and in fine, a litte more "C+".
Also, I think my core skillset and interests lie in the realm of programming on microcontrollers, and that paradigm is inherently bad for use with the STL and is tightly coupled with and benefited by the use of raw pointers, raw structs, raw buffers, and register memory mapping. I am generally opposed to increased type safety at the cost of reduced simplicity / greater verbosity and greater complexity. This frequently puts me at odds with many other C++ developers, but when I look at the massively-complex systems produced by choosing type-safety first, it leaves a lot to be desired, and the increased mental overload, potentially-increased propensity for human errors, and decreased speed isn't worth the cost. I hypothesize that reducing complexity and choosing simplicity over type-safety will ultimately make your code cleaner and safer, more efficient, easier to maintain, less expensive, and better all around.
====================================================================================================
= Time Estimation of Projects/Tasks/Tickets/Pull-Requests: =
====================================================================================================
THE PROBLEM:
I find that I am pretty bad at time estimations, so I want to jot down some notes here to help me think about the problem better. I'm frequently off by as much as a factor of 2x to 5x, which is horrible. Ex: I estimate a certain task will take 2 days. I forget, however, that that is **ideal**, uninterrupted, "in the zone" time, and even then it's optimistic because I'm **hoping** to get it done sooner by just working really hard, or really long hours. So, that ends up being two 13 or 14 hour days, which sucks and is unsustainable, and that's only to get my project prototyped and pushed for review, NOT to get it also tested, approved, or merged, or in the case of free-lance work, polished off and fully handed over and paid for.
THE FIX:
Have realistic time estimates. So, if I think to myself "this'll take 2 days," then I need to remind myself: "Oh, wait, that's 2 **ideal** days, possibly even 13 hours each day. This isn't BattleBots anymore. I can't work like that." "Ok, so this is really 4 days + 1 day for testing. ===> This'll take 5 days. <=== SOLVED!"
A programming task/project might take:
* 2 ideal "Battlebots" prep/build days of work. That means 13-hour days with no human interaction, little food, no showers, and pure focus. This isn't practical, and definitely doesn't work in a corporate environment, **especially** where others control your work and determine whether or not it's "good enough" (or, more frequently: it must meet their subjective standards) to land on the code base.
So, the REAL ESTIMATE IS: <======== THIS! ======= (2 days is actually 5 days--possibly even 6)
* 2 normal human (8 hrs.) days of work for me to do the main coding (bug fix or new feature)
* + 2 days for writing unit tests, doing bench or field testing, etc.
* + 1 day *minimum* for review, fixing, merging the code, etc.
= 5 days total. You may even throw in a 6th day (ie: 1 more day) for researching, as that is inevitably required if there are a lot of unknowns or you are not already **intimately** familiar with the code, project, technology, libraries, code base, etc.
- AND THEN, ***ON TOP OF THIS***, you must assume that these 5 days of work will be done at 60% efficiency, due to meetings and things, meaning it will actually take 5/0.6 = 8.33 days, or 1 week 3.33 days, assuming 5-day work weeks and 8-hr work days.
**************************************************************************************************
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
So...in actual, real-life timeline days for project planning and making Gant charts and finding critical paths and things, "2 days" of work (according to how I used to think about work in my BattleBots-mentality build days) will take **1 week 3.33 days** in the corporate environment or work-place, where you work 5-day work weeks, 8~9-hr. days, at 60% time efficiency. <===== THIS IS THE KEY TAKEAWAY! ===
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
**************************************************************************************************
***Start multiplying all your estimates by 2.5 from now on*** until you can get this cemented into your brain about how real-world projects go, especially when you're working on a team or working with others, and even more-so when you don't own the project and get to make every executive decision by yourself like your own little project dictator. This is the reality of corporate programming/software development, and probably how it would be in the true customer-focused world as well, where you are not essentially your own customer and micro-dictator.
ANOTHER WAY TO LOOK AT IT:
(ESTIMATING EXAMPLE/COMPARATIVE ANALYSIS):
(In parenthesis is an example number of days for each task for relative comparison between these tasks):
1. (2 days) doing the actual coding work and pushing my code change for review, considering 8 hr. days where I might only be productive for 4 or 5 of those hrs., or ~60% max efficiency due to meetings and things.
2. (1 day) fixing broken modules or having to dig into things I didn't expect, due to large, complex projects; this might include having to do additional research and things
3. (2 days) writing unit tests and doing testing; ex: bench, running and fixing unit tests, etc.
4. (1 day) code review and merging, assuming ideal conditions (this could easily be 2 to 6+ days if a bunch of changes are requested)
Total = 2 + 1 + 2 + 1 = 6 days of actual work for a task which I might take only 2 days to do if it was a 100% self-owned project I am familiar with, in my personal time. And...if big changes are requested during code review, these 6 days quickly become 7 to 11+ days, especially if new bench and field testing and new unit tests are required for a major change or re-architecture as well.
BREAKDOWN:
1. 2/6 days = 1/3 = 33% of my total time is actually coding up the new feature or bug fix.
2. 1/6 days = 17% might be just researching new tools or code syntax or modules or tools or whatever, again, in ideal conditions. In completely brand-new conditions this could be as high as 2 or 3 up to 5 or 6+ days.
3. 2/6 days = 1/3 = 33% is writing new tests or doing testing
4. 1/6 days = 17% is getting review, writing descriptions and updating documentation, and that's assuming NO or MINIMAL changes are requested. If they request an entire re-architecture or rip-up, this could easily expand to 2 or 3+ days just to go back and repeat step 1 above ALONE, which originally took 2 days. Then, you'd have to redo steps 2 to 4 as well which would take ANOTHER 4+ DAYS ON TOP OF THAT. So, if major re-architecture is required, this is a good time to notify your boss (or customer, if you are your own boss/a freelancer or sole proprietor), and inform him/her of the delay, request more time, and re-evaluate how code review and new design is handled and discussed on the team, as it *may* (but doesn't necessarily) indicate a failure to plan ahead and communicate in advance, which could need addressing at a procedural/systemic level.
I talked to a smart guy who said, ***"no ticket [task] takes less than 2 hrs."*** He said, "If I have a task to send an email, I schedule 2 hours"..."because inevitably you will be interrupted or something will happen and that 2 hours will quickly be filled up."
KEY TAKE-AWAY: scheduling *at least* 2 hours for even the most minute of tasks is required if you hope to become a person who can (quote/un-quote) "get things done 'on time'". <====== KEY TAKEAWAY! ======
So, ***NEVER SCHEDULE LESS THAN 2 HRS FOR ANYTHING--NOT EVEN THE MOST TRIVIAL OF TASKS AT WORK (OR ON OTHER PAID OR SCHEDULE-BASED PROJECTS)!*** AND IF SOMETHING MUST LAND ON A LARGE CODE BASE WHERE LOTS OF OTHER PEOPLE ARE INVOLVED, MAKE IT NO LESS THAN 4 HRS.! <========== REMEMBER THIS! ==========
====================================================================================================
= Stack Overflow and Other Stack Exchange Sites: =
====================================================================================================
== How to NOT get suspended from Stack Exchange sites: ==
[SEE ALSO THE UPDATE/OFFICIAL CORRESPONDENCE BELOW!]
1. Follow the **Full Disclosure rule:** EVERY time you post ANYTHING to a personal or professional site, project, tool, or product to which you are affiliated, ESPECIALLY when you solicit donations, have ads, sell it, or otherwise might many money from it, even if only $1 over the course of a year, EXPLICITLY STATE YOUR AFFILIATION! Ex:
"Full Disclosure: I wrote/helped write/build/help build/maintain/help maintain this [tool] which can do ___."
Or perhaps just:
"Full Disclosure: I wrote this."
Then state how and why it is useful and relevant to the Original Poster's exact question, and not just a random act of self-promotion or spam.
2. "**You have to show your tool/library actually solves the problem:** that means you have to write the 10 lines of code that call your library, and it is helpful if you **show an actual result,** and even better if you [show] a result based on the code in [the OP’s (Original Poster's) example code]."
~Source: direct quote from Ira Baxter (this quote isn't from here, but here's who he is: https://stackoverflow.com/users/120163/ira-baxter).
My own summary of this quote: _provide an actual example, **including output or screenshots**, of your external tool, library, or resource. Preferably make it exactly specific to the question at hand._
This demonstrates your tool 1) actually works, and 2) actually solves the OP's problem and hence isn't just random spam or random self-promotion.
=== Related References, Sources, and Resources: ===
1. [How to not be a spammer](https://arduino.stackexchange.com/help/promotion) - very important link which backs up the above two main rules! Two key takeaways are: 1) "you _must_ disclose your affiliation in your answers", and 2) "Don't tell - show!"..."demonstrate a solution rather than simply asserting the problem can be solved." They also have other great points, such as "always solve the asker's problem," and "avoid poorly-written questions", because a well-written answer to a poorly-worded question looks even more spammy to many other people than a poorly-worded answer to a poorly-worded question, oddly enough (personal note: this is an example of the conundrum of "if it looks like you tried too hard, it's probably because you're getting paid to do it" [and therefore what you say isn't as true or as valid], which is asinine and ridiculous but this is what "normal" people think apparently).
2. https://arduino.stackexchange.com/help/behavior
3. [very interesting real-life case] https://meta.stackexchange.com/questions/57497/limits-for-self-promotion-in-answers/59302#59302
4. [my own question] https://meta.stackexchange.com/questions/351349/is-the-new-software-recommendations-stack-exchange-a-trap-to-catch-people-who?noredirect=1#comment1176694_351349
See also:
1. https://stackoverflow.com/help/deleted-answers
2. https://stackoverflow.com/help/locked-posts
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
== UPDATE: Official and personal correspondence with me from a Stack Overflow employee (not moderator, but actual, paid employee): ==
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> In terms of official guidance regarding your personal website links being included, I would recommend you to read these two answers:
>
> 1. [What is the exact definition of "spam" for Stack Overflow?](https://meta.stackoverflow.com/questions/260638/what-is-the-exact-definition-of-spam-for-stack-overflow/260641#260641)
> 2. [What are the "spam" and "rude or abusive" (offensive) flags, and how do they work?](https://meta.stackexchange.com/questions/58032/what-are-the-spam-and-rude-or-abusive-offensive-flags-and-how-do-they-wor/58035#58035)
>
> You can include links to your site, but please be careful with that and make sure that:
>
> 1. The person can understand the answer fully without having to follow the link.
> 2. You disclose that it is your personal website. [My notes: according to the 2nd link he gave me just above, "a simple 'my' may suffice", so simply saying something like this (emphasis added): "refer to **my website** here for more information on ___" is perfectly acceptable].
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
== How to appeal a Code of Conduct violation or suspension if you ever get wrongfully suspended from a Stack Exchange/Stack Overflow Site: ==
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Examples:
1. From any page on https://arduino.stackexchange.com/: scroll to the bottom of the page --> click the "Contact" link (https://arduino.stackexchange.com/contact) --> click the "What can we help you with?" dropdown menu --> choose the "I want to appeal a Code of Conduct violation" option --> politely explain your situation and submit it. Note that your description must be < 5000 chars, which apparently includes any HTML/XHTML/XML? post-formatting they add to your description, so that gives you about 4800~4900 or so chars to write your description. This will be sent to a paid Stack Overflow employee, *not* an unpaid community moderator, a Jira ticket will be opened for your case, you will be sent an email with instructions to open a Jira account to monitor and reply to your case, and they will work on it over the next 3 to 4 or so weeks.
2. From any page on https://stackoverflow.com/: scroll to the bottom of the page --> click the "Contact Us" link (https://stackoverflow.com/company/contact) --> click the "contact us" link now at the top of the page under the "Support & Feedback" heading (https://stackoverflow.com/contact?referrer=https%3a%2f%2fstackoverflow.com%2f) --> --> click the "What can we help you with?" dropdown menu --> choose the "I want to appeal a Code of Conduct violation" option --> politely explain your situation and submit it (see above for more details and notes about the character limits for the description section).
====================================================================================================
= Doxygen: =
====================================================================================================
See other examples here:
1. http://www.doxygen.nl/manual/commands.html
1. https://stackoverflow.com/questions/15398711/whats-the-right-way-to-reference-a-parameter-in-doxygen/56745246#56745246
1. https://stackoverflow.com/questions/34196663/stm32-how-to-get-last-reset-status/54728664#54728664
1. https://stackoverflow.com/questions/385975/error-handling-in-c-code/59221452#59221452
Here's a bunch of Doxygen examples for easy copy/pasting into your code when you are frequently writing Doxygen:
Full Doxygen function header example:
/// \brief A brief one or two line description of the function.
/// \note An important note the user should be aware of--perhaps many lines.
/// \details Extra details.
/// Perhaps
/// even
/// a long
/// paragraph.
/// \param[in] var1 Description of variable one, an input
/// \param[in] my_longer_var2 Description of variable two, an input
/// \param[out] var3 Description of variable three, an output (usu. via a pointer
/// to a variable)
/// \param[in,out] var4 Description of variable four, an input/output (usu. via a
/// pointer) since its initial value is read and used, but then
/// it is also updated by the function at some point
/// \return Description of return types. It may be an enum, with these
/// possible values:
/// - #ENUM_VALUE_1
/// - #ENUM_VALUE_2
/// - #ENUM_VALUE_3
my_enum_t myFunc(int var1, int var2, int* var3, int* var4)
{
// function implementation here
my_enum_t error = ENUM_VALUE_1;
// Check for NULL pointers
if (!var3 || !var4)
{
// var3 or var4 are NULL pointers, which means they can't be dereferenced
error = ENUM_VALUE_2;
goto done;
}
if (something_else)
{
error = ENUM_VALUE_3;
goto done;
}
done:
return error;
}
You may also use `@` instead of `\`:
/// @brief A brief one or two line description of the function.
/// @param[in] var1 Description of variable one, an input
/// @param[in] my_longer_var2 Description of variable two, an input
/// @param[out] var3 Description of variable three, an output (usu. via a pointer
/// to a variable)
/// @param[in,out] var4 Description of variable four, an input/output (usu. via a
/// pointer) since its initial value is read and used, but then
/// it is also updated by the function at some point
/// @return None
void myFunc(int var1, int var2, int* var3, int* var4)
{
// function implementation here
}
And here's this shorter version again now with `\` again instead of `@`:
/// \brief A brief one or two line description of the function.
/// \param[in] var1 Description of variable one, an input
/// \param[in] my_longer_var2 Description of variable two, an input
/// \param[out] var3 Description of variable three, an output (usu. via a pointer
/// to a variable)
/// \param[in,out] var4 Description of variable four, an input/output (usu. via a
/// pointer) since its initial value is read and used, but then
/// it is also updated by the function at some point
/// \return None
void myFunc(int var1, int var2, int* var3, int* var4)
{
// function implementation here
}
And the more compact versions of the above (assumes shorter parameter names, and only [in] or [out] params but no [in,out] params):
/// @brief A brief one or two line description of the function.
/// @param[in] variable_1 Input parameter
/// @param[in] variable_2 Another input parameter
/// @param[out] variable_3 Output parameter
/// @param[out] variable_4 Another output parameter
/// @return None
void myFunc(int var1, int var2, int* var3, int* var4)
{
// function implementation here
}
/// \brief A brief one or two line description of the function.
/// \param[in] variable_1 Input parameter
/// \param[in] variable_2 Another input parameter
/// \param[out] variable_3 Output parameter
/// \param[out] variable_4 Another output parameter
/// \return None
void myFunc(int var1, int var2, int* var3, int* var4)
{
// function implementation here
}
====================================================================================================
= Python Docstrings: =
====================================================================================================
Useful for documenting Python functions and classes. Python docstrings are like the "doxygen" of Python. ~GS
References:
1. https://stackoverflow.com/questions/3898572/what-is-the-standard-python-docstring-format
1. My own examples from my own code: https://github.com/ElectricRCAircraftGuy/git-tree/blob/master/git-tree.py
General format:
def my_func(self, param1, param2, param3, param4):
"""
Function to do whatever.
Parameters:
param1 (string): string to do ___
param2 (int): integer between the range of __ and __ to be used for __
param3 (list of MyClass objects): list of myClass objects for __
param4 (dict of string:string key:values): map from something1 to something2, to be used
for __ and __ in order to __
Returns:
dict of string:MyClass key:value pairs mapping a name string to a MyClass object
"""
Another random "Returns" example:
"""
Returns:
(string, list of dicts, list of numbers) tuple
"""
Example from my own code (see my git-tree.py link above):
def __init__(self, name, parent = None):
"""
Constructor to create a new Node.
Parameters:
name (string): the name of this node
parent (Node): the parent node of the node being created; note: obviously the parent node must already
exist in order to be passed in as a parameter here
Returns:
NA
"""
# Do constructor stuff here
Alternative General format [MY PREFERRED PYTHON DOCSTRING FORMAT NOW I THINK]:
- Note: see Python Built-in Exceptions here: https://docs.python.org/3/library/exceptions.html
def my_func(self, param1, param2, param3, param4):
"""
Function to do whatever.
For python exception-handling help and examples, see:
https://www.w3schools.com/python/python_try_except.asp
-----------
Parameters:
-----------
param1: str
String to do ___.
param2: int
Integer between the range of __ and __ to be used for __.
param3: list of MyClass objects
List of myClass objects for __.
param4: dict of {string:string} key:value
Map from something1 to something2, to be used for __ and __ in order to __.
param5: list of ints
List of integers representing __.
--------
Returns:
--------
dict of {string:MyClass} key:value pairs
Map of a name string to a MyClass object.
-------
Raises:
-------
TypeError:
If `param2` is not an integer.
ValueError:
If input parameter `param2` has the right type but an invalid (out-of-range) value.
See: https://docs.python.org/3/library/exceptions.html#ValueError
SystemError:
If whatever (detailed description goes here).
"""
if not type(param2) is int:
raise TypeError("param2 must be an int.")
if not (0 <= param2 <= 100):
raise ValueError("param2 must be between 0 and 100, inclusive.")
try:
# do some stuff here
except SystemError:
print("Some descriptive message; output_data = \n{}.".format(output_data))
raise # re-raise the exception to crash the program
my_class = MyClass(param1, param2)
some_str = "hello"
my_class2 = MyClass(param1 + some_str, param2 + 724)
my_dict = {param1: my_class, some_str: my_class2}
return my_dict
====================================================================================================
= bazel: =
====================================================================================================
Good example to get started in Bazel: https://github.com/ElectricRCAircraftGuy/eRCaGuy_gtest_practice
Config files:
1. BUILD (old, but still widely-used)
1. BUILD.bazel (new, but still not widely-accepted, and is somewhat debated) [see note 1 below]
1. WORKSPACE
1. .bazelrc in your workspace directory (next to the main WORKSPACE file); see: https://docs.bazel.build/versions/master/guide.html#where-are-the-bazelrc-files
1. user.bazelrc in your workspace directory (next to the main .bazelrc file); see: https://docs.bazel.build/versions/master/best-practices.html#bazelrc. Add an entry for `user.bazelrc` to your ".gitignore" file for your git repo, so that this becomes a custom user bazelrc file which does NOT get checked-in to the main git repo! Then, in your main git repo's ".bazelrc" file, add the command `try-import user.bazelrc` at the end to automatically import a user's custom "user.bazelrc" file if it exists!
Notes:
[1] GS: for all new projects, I recommend using `BUILD.bazel` over `BUILD`. See here:
1. [In Docs: clarify BUILD vs. BUILD.bazel #4517](https://github.com/bazelbuild/bazel/issues/4517) - brings up the fact this is an on-going debate.
1. https://docs.bazel.build/versions/master/build-ref.html#packages - shows both as valid options: `BUILD.bazel` and `BUILD`.
Bazel Online Documentation:
1. See all Bazel commands here (ie: `bazel --[startup options] <cmd> --[cmd options]`): https://docs.bazel.build/versions/master/command-line-reference.html#commands
1. See all Bazel options online here! https://docs.bazel.build/versions/master/command-line-reference.html. Ex:
1. Sub-categories of options:
1. All `bazel build` options: https://docs.bazel.build/versions/master/command-line-reference.html#build-options
1. All `bazel test` options: https://docs.bazel.build/versions/master/command-line-reference.html#test-options
1. All `bazel query` options: https://docs.bazel.build/versions/master/command-line-reference.html#query-options
1. etc.
1. To pass in Java Virtual Machine (JVM) options, such as heap size, as Bazel startup options: https://docs.bazel.build/versions/master/command-line-reference.html#flag--host_jvm_args
--host_jvm_args=<jvm_arg>
2. To limit how many of your local CPUs Bazel can use. Note that HOST_CPUS here is probably (and usually is) 1/2 the number of cores you have. So, if gnome-system-monitor shows you have 8 cores, you may only have 4 CPUs.: https://docs.bazel.build/versions/master/command-line-reference.html#flag--local_cpu_resources
--local_cpu_resources=<an integer, or "HOST_CPUS", optionally followed by [-|*]<float>.> default: "HOST_CPUS"
NB: THIS cpu resource limiter option above doesn't actually work very well! Frequently, even with it in-use, the CPU usage will still lock out at 100% for periods of many minutes at a time! To prevent this, just use the Linux `cpulimit` program in a separate terminal!:
cpulimit -p <pid> -l 500 # limit your bazel build to 62.5% max CPU usage on an 8-core machine
Read more about the above command in the "Limit CPU usage" section of this document down below.
3. To limit local RAM usage: https://docs.bazel.build/versions/master/command-line-reference.html#flag--local_ram_resources
--local_ram_resources=<an integer, or "HOST_RAM", optionally followed by [-|*]<float>.> default: "HOST_RAM*.67"
4. To disable remote caching: https://docs.bazel.build/versions/master/command-line-reference.html#flag--remote_cache
--remote_cache=""
1. To share build outputs between users, for saving hard drive space, use bazel startup option:
--output_user_root=<path>
See: https://docs.bazel.build/versions/master/command-line-reference.html#flag--output_user_root
Ex:
bazel --output_user_root="/home/some_other_user/.cache/bazel" build //...
1. "A user's guide to Bazel" - https://docs.bazel.build/versions/master/guide.html
1. Specifying targets to build (`bazel build //...` [build the whole project], `bazel build //:all` [build just the top-level build targets], etc.) -
https://docs.bazel.build/versions/master/guide.html#specifying-targets-to-build
1. Macros (Bazel build rule macros--used to generate build targets):
1. Macros: https://docs.bazel.build/versions/master/skylark/macros.html
1. Expanding macros [macro expansion in Bazel; Bazel macro expansion; expanding macros in Bazel; Bazel expanding macros]: https://docs.bazel.build/versions/master/skylark/macros.html#expanding-macros. To see their expanded forms:
time bazel query --output=build //path/to/my/target/... > out.txt # Store the expanded form of all macros/build rules into out.txt
subl out.txt # open out.txt in Sublime Text 3
1. Creating a macro: https://docs.bazel.build/versions/master/skylark/tutorial-creating-a-macro.html
1. Bazel "Make" Variables [bazel make variables]: *****https://docs.bazel.build/versions/master/be/make-variables.html
1. Ex: `my_attr = "prefix $(FOO) suffix"` = insert the Bazel "Make" (GNU Make-like) variable `FOO` into this attribute.
Bigger example, with a `genrule()` (https://docs.bazel.build/versions/master/be/general.html#genrule) which runs during `bazel build` to run some bash command-line call, during the build, to do something like auto-generate some files required as C++ `srcs` and headers later in the build, for example:
# =================================
# "src/module1/BUILD" file:
# =================================
# `py_binary()`: see: https://docs.bazel.build/versions/master/be/python.html#py_binary
py_binary(
name = "generate_files",
main = "scripts/generate_files.py",
srcs = [
"scripts/generate_files.py",
"scripts/do_xyz.py",
],
deps = [
"//some/module:py_library_rule",
],
)
# =================================
# "src/module2/BUILD" file:
# =================================
# The Python script run by the genrule below will need to read in and parse all of these files
filegroup(
name = "data_files_for_genrule",
srcs = [
"data/file1.txt",
"data/file2.csv",
"data/file3.py",
"yaml/yaml1.yaml",
":another_file_group",
],
)
# See what the variable-substituted version/output of this is with:
# bazel query --output=build //src/module2:run_this_python_script_during_build
genrule(
name = "run_this_python_script_during_build", # <== (that's what a genrule does!)
srcs = [
":data_files_for_genrule", # a filegroup from this same BUILD file
"//some/package:another_filegroup", # a filegroup from another package
"data/file10.txt", # a local file; relative path from this BUILD file's dir
],
# Files not in this `outs` Starlark (Python3-like) list will be deleted by Bazel after
# this genrule() runs, so any files which this script generates MUST be in this list
# for them to persist and be available for later parts of this build! So, add all
# (generated-by-this-script) files to `outs` that you need to NOT be deleted by Bazel!
outs = [
"mymodule/autogen/file1.h",
"mymodule/autogen/file1.cpp",
"mymodule/autogen/file2.cpp",
"mymodule2/autogen/file1.csv",
"mymodule2/autogen/file1.yaml",
],
# See meaning of `execpath`, used in this Bazel "Make" variable, here:
# https://docs.bazel.build/versions/master/be/make-variables.html#predefined_label_variables
cmd = (
'$(execpath //src/module1:generate_files) '
'--option1 "something" '
'--option2 "something else" '
'--option3 12973 '
# Pass in all `outs` items to the script itself, if desired, to process. `OUTS` here
# is a Bazel "Make" variable.
# See: https://docs.bazel.build/versions/master/be/make-variables.html
'--bazel_outs "$(OUTS)" '
# Pass in the Bazel `srcs` list too via this Bazel "Make" variable. See link above.
'--bazel_srcs "$(SRCS)" '
),
visibility = [
"//visibility:private",
],
)
NOTES:
In the `genrule()` above, you could also do the command like this:
cmd = (
# I *think* this path relative to the project root dir would work:
'//src/module1/scripts/generate_files.py '
# OR if the file was local to this module, just call it with a path relative to this module:
'scripts/generate_files.py '
# Instead of this:
# '$(execpath //src/module1:generate_files) '
'--option1 "something" '
'--option2 "something else" '
'--option3 12973 '
'--bazel_outs "$(OUTS)" '
'--bazel_srcs "$(SRCS)" '
),
...or like this, if you wanted to join the command as a list of strings (joined by a single
space) instead. Notice the deleted space before the ending single quote on each line, and the
added comma after the single quote to make this a list of strings now instead of a
continuous, multi-line string!
cmd = ' '.join([
'$(execpath //src/module1:generate_files)',
'--option1 "something"',
'--option2 "something else"',
'--option3 12973',
'--bazel_outs "$(OUTS)"',
'--bazel_srcs "$(SRCS)"',
]),
REFERENCES FOR THE ABOVE EXAMPLE:
1. *****https://docs.bazel.build/versions/master/be/make-variables.html
1. https://docs.bazel.build/versions/master/be/python.html#py_binary
1. https://docs.bazel.build/versions/master/be/general.html#genrule
1. https://docs.bazel.build/versions/master/be/general.html#filegroup
1. EXAMPLE `genrule()` & BUILD file from Bazel, with a custom rule from a custom `defs.bzl`
file!: https://github.com/bazelbuild/examples/blob/master/make-variables/testapp/BUILD
1. `bazel query` example to show *exactly* what the above `genrule()` would look like AFTER full
variable substitution into it:
bazel query --output=build //src/module2:run_this_python_script_during_build
1. See what predefined Bazel "Make", and Bazel environment variables exist for your Bazel build environment.
See: https://docs.bazel.build/versions/master/be/make-variables.html#predefined_variables
bazel info --show_make_env [build options] = shows all predefined "Make" variables in all caps at the top, and bazel environment variables in lowercase thereafter
1. See here for details on the Bazel "output directory layout"!: https://docs.bazel.build/versions/master/output_directories.html
See also the `bazel info` commands just below!
bazel info --show_make_env [optional: build options]
bazel info --show_make_env
see just above! It shows all predefined Bazel "Make" variables [bazel make variables] in ALL CAPS at the very top, and then Bazel environment variables, such as genfiles, bin, etc. output and build paths right after that! See here for details on the Bazel "output directory layout"!: https://docs.bazel.build/versions/master/output_directories.html <==== VERY USEFUL TO BE ABLE TO SEE WHERE ALL BUILD OUTPUT WILL BE PLACED FOR A GIVEN SET OF BUILD SETTINGS! ====
bazel info
<==== VERY USEFUL! ====
Show ALL the `bazel info` variables at once!
Similar to the above, but show JUST the Bazel environment variables (output/build dirs and things), and NOT the Bazel "Make" variables as well!
For `bazel info` options, see here: https://docs.bazel.build/versions/master/command-line-reference.html#info.
bazel info bazel-bin
show the full path to the bazel output "bin" directory
bazel help
See generic bazel help information, including the `bazel help info-keys` cmd.
bazel --help
Same as above
bazel help info
See bazel help for the `bazel info` cmd used just above! This is a lot of information, so, even better: pipe it to `less`!:
bazel help info | less -RFX
Same as above, except piped to `less` for easy viewing. Note that right aft the top of the help it shows:
Usage: bazel info <options> [key]
And:
The full list of keys and the meaning of their values is documented in
the bazel User Manual, and can be programmatically obtained with
'bazel help info-keys'.
bazel info <options> [key]
The generic `bazel info` cmd format, as shown in the help menu just above.
bazel help info-keys
<================
Print all of the keys which can be queried with the `bazel info` cmd above, and a description of what they mean! Example: `bazel info output_base`.
Sample output:
$ bazel help info-keys
bazel-bin Configuration dependent directory for binaries.
bazel-genfiles Configuration dependent directory for generated files.
bazel-testlogs Configuration dependent directory for logs from a test run.
build-language A protobuffer with the build language structure
character-encoding Information about the character encoding used by the running JVM.
client-env The specifications that need to be added to the project-specific rc file to freeze the current client environment
command_log Location of the log containing the output from the build commands.
committed-heap-size The amount of memory in bytes that is committed for the Java virtual machine to use
default-package-path The default package path
defaults-package Obsolete. Retained for backwards compatibility.
execution_root A directory that makes all input and output files visible to the build.
gc-count Number of garbage collection runs.
gc-time The approximate accumulated time spend on garbage collection.
install_base The installation base directory.
java-home Location of the current Java runtime.
java-runtime Name and version of the current Java runtime environment.
java-vm Name and version of the current Java virtual machine.
max-heap-size The maximum amount of memory in bytes that can be used for memory management.
output_base A directory for shared bazel state as well as tool and strategy specific subdirectories.
output_path Output directory
package_path The search path for resolving package labels.
peak-heap-size The peak amount of used memory in bytes after any call to System.gc().
release bazel release identifier
repository_cache The location of the repository download cache used
server_log bazel server log path
server_pid bazel process id
starlark-semantics The effective set of Starlark semantics option values.
used-heap-size The amount of used memory in bytes. Note that this is not a good indicator of the actual memory use, as it includes any remaining inaccessible memory.
used-heap-size-after-gc The amount of used memory in bytes after a call to System.gc().
workspace The working directory of the server.
bazel info | grep -o '.*: ' | rev | cut -c3- | rev
Read just available keys from the output of `bazel info`!
See also this help on how to use `rev | cut -c3- | rev`: https://stackoverflow.com/a/39013253/4561887.
Sample output:
$ bazel info | grep -o '.*: ' | rev | cut -c3- | rev
bazel-bin
bazel-genfiles
bazel-testlogs
character-encoding
command_log
committed-heap-size
execution_root
gc-count
gc-time
install_base
java-home
java-runtime
java-vm
max-heap-size
output_base
output_path
package_path
release
repository_cache
server_log
server_pid
used-heap-size
workspace
bazel info | grep -o '.*: ' | grep -o '[^: ]*'
Alternative way to get the exact same list of keys from the `bazel info` output as shown just above!
bazel info output_base
Show the output directory of the bazel build + sources, including external sources.
See: https://bazel.build/docs/external?hl=en#layout
Sample output:
$ bazel info output_base
/home/gabriel/.cache/bazel/_bazel_gabriel/04bc77638a312ceaca7e62e095dc00bc
ls "$(bazel info output_base)"
List all contents of the output_base directory (shown above).
ls -d "$(bazel info output_base)"/*/
List only the **directories** within the output_base dir!
See also here for the `/*/` part help at the end: https://stackoverflow.com/a/14352330/4561887
Example output. Notice the 4 directories in this "output_base" dir!: "execroot", "external", "install", and "server":
$ ls -d "$(bazel info output_base)"/*/
/home/gabriel/.cache/bazel/_bazel_gabriel/04bc77638a312ceaca7e62e095dc00bc/execroot/
/home/gabriel/.cache/bazel/_bazel_gabriel/04bc77638a312ceaca7e62e095dc00bc/external/
/home/gabriel/.cache/bazel/_bazel_gabriel/04bc77638a312ceaca7e62e095dc00bc/install/
/home/gabriel/.cache/bazel/_bazel_gabriel/04bc77638a312ceaca7e62e095dc00bc/server/
ls "$(bazel info output_base)/external"
<======= VERY USEFUL! ========
IMPORTANT FOLDER! This "external" folder should be considered like an extension of your source code, whenever using bazel! It will house all bazel-downloaded external libraries which are dependencies to your bazel-based projects. So, if you consider your main source code dir PLUS (+) this "$(bazel info output_base)/external" dir to be all part of the source code you are using, then that is correct.
Adding this "external" dir to your IDE indexer, and/or `grep`ping within this "external" dir may be useful whenever you are searching for functions or things within certain external dependencies your source code is using! This allows you to see whatever source code or implementation details or code-based documentation you may need to see when browsing your source code and looking in the external libraries used by your source code.
./update_symlink_to_external.sh
Update the symlink to the Bazel "external" dir found just above, assuming this "update_symlink_to_external.sh" script is executable and contains the following code:
```
#!/bin/bash
FULL_PATH_TO_SCRIPT="$(realpath "$0")"
SCRIPT_DIRECTORY="$(dirname "$FULL_PATH_TO_SCRIPT")"
target_dir="$(bazel info output_base)/external"
echo "Creating symlink to dir \"$target_dir\" inside \"$SCRIPT_DIRECTORY\"."
ln -svnrf "$target_dir" "$SCRIPT_DIRECTORY"
```
You should then add this symlink dir to your Eclipse (or other IDE) project, as a virtual folder or otherwise, and as required, to bring them in to be indexed so you can search, navigate, and browse any external source code libraries as needed.
INSTALLATION:
Something like this would work:
```
cd path/to/repo
mkdir -p GS/external
gedit GS/external/update_symlink_to_external.sh
# copy and paste the above code into this script now; then:
chmod +x GS/external/update_symlink_to_external.sh
# Now you **may** want to either exclude this dir in your `.gitignore` file:
echo '/GS/' >> .gitignore
# OR just locally for yourself in your private `.git/info/exclude` file:
echo '/GS/' >> .git/info/exclude
```
bazel fetch //path/to/some_dir:some_target
Fetch all dependencies (ex: sub-repos, submodules, executables, libraries, etc.) to path "$(bazel info output_base)/external" which are needed by this target!
bazel fetch //path/to/some_dir/...
Fetch all dependencies (ex: sub-repos, submodules, executables, libraries, etc.) to path "$(bazel info output_base)/external" which are needed by **these several targets!**
bazel fetch <targets>
General form of the above.
bazel help fetch
See all options for `bazel fetch`. Note: run `bazel help` or `bazel --help` instead to see a list of all bazel cmds, such as `bazel fetch`.
---
UPDATE: FETCHING IS NOT ENOUGH!
See my full description of what to do here: https://github.com/bazelbuild/bazel/issues/14058#issuecomment-1055015665
Do this!:
```
BUILD_TARGET="//some/path/to/a/build/target/which:requires_my_dependency"
# manually delete the "external" folder you've edited, once you're done editing it and
# want to restore it to how it was originally
{EXTERNAL_DEPS_ROOT}="$(bazel info output_base)/external"
EXTERNAL_DEP="some_dependency_repo_name"
rm -rf "${EXTERNAL_DEPS_ROOT}/${EXTERNAL_DEP}"
# force bazel to re-download this dependency!:
# Note: this is a bit of a hack, but it works.
# See: https://github.com/bazelbuild/bazel/issues/14058#issuecomment-1031520021
time bazel sync --only=$BUILD_TARGET