Setting up a Software Development Environment for macOS and Ubuntu Linux



I show how to set up a software development environment for macOS and Ubuntu Linux. When we're done, we'll be able to develop programs in C, C++, Python, Javascript, and Lisp using Unix tools.

SYSTEM SETUP - Ubuntu Linux

Ubuntu Linux on a CyberPower PC

This platform is a CyberPowerPC Series C 2019 ET8880-1202 with an AMD motherboard, 1TB SATA disk drive, wireless PCI module, GPU card, Acer monitor, USB keyboard and three button mouse. To install Ubuntu Linux 22.04.1 LTS (Jammy Jellyfish) follow the excellent Ubuntu Desktop Installation instructions.

CyberPower PC CyberPower PC Side View

Here are the steps I used:

  1. Download the Ubuntu distribution for an Intel PC ubuntu-22.04.1-desktop-amd64
  2. Download and install Balena Etcher balenaEtcher-1.7.9.dmg for Mac OS. Balena Etcher Plug in a 16GB USB Drive into my MacBook Pro. Select the ISO and Drive and copy Ubuntu to USB drive.
  3. When etched, insert the USB drive into the PC, hold down the F2 key and boot into the boot loader screen. Make the USB drive the first option. Boot Options Exit and reboot.
  4. Click on the Install Ubuntu button on the screen. Install Ubuntu
  5. Connect to wireless hub. Wireless
  6. Allow third party software. Wireless
  7. Erase install. Wireless
  8. User name and password. User name and password

Then continue to the end of the install.

Installing Drivers for the GPU

My machine has a GPU card, an AMD XFX Radeon RX570 4GB OC+ 1386 MHz DDR5 3xDP HDMI DVI board. It was painful to get working drivers installed. Go to AMD Support, and download the drivers SW for this version of Linux. The steps in my case were:

cd ~/Downloads sudo apt-get install ./amdgpu-install_22.20.50200-1_all.deb sudo apt-get update amdgpu-install --opencl=rocr --pro --accept-eula amdgpu-install --usecase=workstation -y --opencl=rocr

Install this stuff too:

sudo apt-get install mesa-utils sudo apt install mesa-opencl-icd sudo apt install clinfo-amdgpu-pro opencl-orca-amdgpu-pro-icd
# Check the AMD GPU board is recognized. sudo lshw -c video *-display description: VGA compatible controller product: Ellesmere [Radeon RX 470/480/570/570X/580/580X/590] vendor: Advanced Micro Devices, Inc. [AMD/ATI] physical id: 0 bus info: pci@0000:1f:00.0 logical name: /dev/fb0 version: ef width: 64 bits clock: 33MHz capabilities: pm pciexpress msi vga_controller bus_master cap_list rom fb configuration: depth=32 driver=amdgpu latency=0 resolution=1920,1080 resources: irq:62 memory:e0000000-efffffff memory:f0000000-f01fffff ioport:f000(size=256) memory:fcf00000-fcf3ffff memory:c0000-dffff

Ubuntu 22.04 LTS has Wayland which replaces X11.

Ubuntu Linux Tweaks

We'll make Ubuntu more useful. First read the Ubuntu Desktop Guide.

Clean up Problems with Your Upgrade

If your upgrade didn't go smoothly, you can install and run aptitude.

sudo apt install aptitude sudo aptitude update man aptitude

Run aptitude to diagnose, clean and reinstall your packages.

sudo aptitude update sudo aptitude upgrade sudo aptitude autoclean
Displaying HEIC Images

To show Apple's HEIC formatted images from iPhones as thumbnails in folders and to view them, follow viewing HEIC photos and do this

sudo apt update sudo apt install heif-gdk-pixbuf sudo apt install heif-thumbnailer

Then right click on one of the HEIC images in file folder and select ImageViewer for this file type: HEIC1 HEIC2

Screen Shots
Use the Space + PrintSysRq buttons to do screen shots
Changing the Terminal Type
I want to execute the bash startup files the same way macOS does. So you need tell Ubuntu to run the terminal window as a login shell:
File Sharing Between Mac and Ubuntu Computers

Install Vim first so you can edit files. Here's how to change the hostname of your system.

# Edit this file and change the name to Gauss cat /etc/hostname Gauss # Edit this file and change the names cat /etc/hosts localhost Gauss ... hostnamectl -h set-hostname --transient Gauss sudo hostnamectl -h set-hostname Gauss sudo hostname Gauss reboot

To install file sharing across computers, find out your username

users seanoconnor

then install Samba, and give a sharing password,

sudo apt-get install samba sudo smbpasswd -a seanoconnor

Let's share the Desktop directory under $HOME. First copy the system config file to your local directory,

sudo cp /etc/samba/smb.conf ~

Edit the smb.conf file by adding these lines to the end,

[share] path = /home/seanoconnor/Desktop valid users = seanoconnor read only = no

Start the Samba client,

sudo apt-get install smbclient sudo service smbd restart

To speed up SMB sharing, (it still takes a minute or two on my Mac), add the IP addresses and hostnames of all your local computers to the /etc/hosts file.

Install ifconfig so you can see the IP addresses.

sudo apt install net-tools

Get the hostname on my Ubuntu Linux computer and its IP address

hostname Gauss ifconfig ... inet 333.333.3.33 netmask broadcast 333.333.3.255 ...

Now go to the macOS computer and get the hostname and IP address,

hostname MacBookProHostName ifconfig ... inet 555.555.5.55 netmask 0xffffff00 broadcast 333.333.3.255 ...

Back in Ubuntu, edit the hosts file by doing sudo vim /etc/hosts. Add these two host names and their IP addresses. localhost ... 333.333.3.33 Gauss 555.555.5.55 MacBookProHostName

Launch the File Manager application. In your Home directory, right click on the Desktop directory to get Properties. Turn on sharing in Local Network Share and allow others to create and delete files.

Finally you must open the firewall for Samba,

sudo ufw allow Samba

Back on macOS, mount the shared remote directory, which will prompt you for the Samba password you just set,

cd ~/Desktop mkdir Ubuntu mount -t smbfs //seanoconnor@Gauss/Desktop ~/Desktop/Ubuntu

You'll see the shared directory on the Ubuntu machine, so go ahead and Connect

Backing Up Your System

Format a 2TB USB drive as ExFAT and give it a name.

Then back up your system with rsync. As the article explains the command is

rsync -aAXHv --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} / /media/seanoconnor/Gauss/Snapshot-23-Sep-22-08_51

The -aAX options transfers files in archive mode. This ensures symbolic links, devices, permissions, ownerships, modification times, ACLs, and extended attributes are preserved, assuming that the target file system supports the feature. The option -H preserves hard links, but uses more memory. The --exclude option causes files that match the given patterns to be excluded. The directories /dev, /proc, /sys, /tmp, and /run are included in the above command, but the contents of those directories are excluded. This is because they are populated on boot, but the directories themselves are not created. The command above depends on brace expansion available in both the bash and zsh shells. Quoting the exclude patterns will avoid expansion by the shell, which is necessary, for example, when backing up over SSH. Ending the excluded paths with * ensures that the directories themselves are created if they do not already exist.

Secure Shell Login

I've followed instructions from the article How to Enable SSH on Ubuntu 18.04 to ssh from my Mac to my Ubuntu on my local net. I haven't tried it yet from outside my router but look at Ubuntu's instructions SSH Server Configuration and Servers Behind NAT

Install the ssh server,

sudo apt install openssh-server

Check the status

sudo systemctl status ssh ● ssh.service - OpenBSD Secure Shell server Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2019-11-29 11:39:54 PST; 33s ago Main PID: 5638 (sshd) Tasks: 1 (limit: 4279) CGroup: /system.slice/ssh.service └─5638 /usr/sbin/sshd -D

Open the firewall

sudo ufw allow ssh Rule added Rule added (v6)

Back on the Mac, ssh into the Ubuntu machine using the IP address. You'll be asked to register an RSA encryption key the first time.

ssh seanoconnor@gauss seanoconnor@gauss's password: Welcome to Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-46-generic x86_64) * Documentation: * Management: * Support: 0 updates can be applied immediately. Last login: Fri Aug 26 17:26:27 2022 from 2600:1700:4384:1210:3d5f:29a6:71db:cc27 Entering Python 3.10.4 virtual environment at /home/seanoconnor/.VENV. Type deactivate to exit. seanoconnor:~$ ls Desktop/ Documents/ Downloads/ Music/ Pictures/ snap/ Templates/ Videos/ logout Connection to gauss closed.
Screen Sharing from Mac to Ubuntu

Follow the Ubuntu instructions to enable screen sharing

I allow only local connections. Check the VNC server status:

gsettings set org.gnome.Vino network-interface lo systemctl --user status gnome-remote-desktop.service ● gnome-remote-desktop.service - GNOME Remote Desktop Loaded: loaded (/usr/lib/systemd/user/gnome-remote-desktop.service; enabled; vendor preset: enabled) Active: active (running) since Sun 2022-09-04 20:17:00 PDT; 1h 2min ago Main PID: 4033 (gnome-remote-de) Tasks: 5 (limit: 9334) Memory: 47.3M CPU: 16.623s CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/gnome-remote-desktop.service └─4033 /usr/libexec/gnome-remote-desktop-daemon Sep 04 20:17:00 Gauss systemd[3712]: Starting GNOME Remote Desktop... Sep 04 20:17:00 Gauss systemd[3712]: Started GNOME Remote Desktop. Sep 04 20:17:02 Gauss gnome-remote-de[4033]: RDP server started Sep 04 20:17:02 Gauss gnome-remote-de[4033]: VNC server started Sep 04 21:13:28 Gauss gnome-remote-de[4033]: Refusing new VNC connection: already an active session

In Terminal you'll see the screen sharing server listening on port 5900

ss -lnt State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 50* . . . LISTEN 0 10 *:3389 *:* LISTEN 0 5 [::]:5900 [::]:*

If you don't have Vino already, you will need to install the Vino tool and verify it and set the encryption to false so macOS Screen Sharing can see it.

sudo apt-get install vino gsettings set org.gnome.Vino require-encryption false gsetgsettings list-recursively org.gnome.Vino | grep encrypt org.gnome.Vino require-encryption false

Open the firewall for the screen sharing port.

sudo ufw allow from any to any port 5900 proto tcp Rules updated Rules updated (v6)

View the firewall settings, which show the VNC screen sharing port 5900, the ssh port 22 and Samba which we allowed earlier.

sudo ufw status Status: active To Action From -- ------ ---- 22/tcp ALLOW Anywhere Samba ALLOW Anywhere 5900/tcp ALLOW Anywhere 22/tcp (v6) ALLOW Anywhere (v6) Samba (v6) ALLOW Anywhere (v6) 5900/tcp (v6) ALLOW Anywhere (v6)

Or use the firewall GUI:

sudo apt install gufw gufw

If that doesn't work you can try installing the TightVNC server according to How to Install and Configure VNC on Ubuntu 22.04

sudo apt install xfce4 xfce4-goodies sudo apt install tightvncserver

Launch the VNC server using


Configure the VNC server by stopping it first.

vncserver -kill :1

Edit the VNC configuration file.

seanoconnor:~/Desktop$ cat ~/.vnc/xstartup #!/bin/bash xrdb $HOME/.Xresources startxfce4 &

Save the original default file which is

seanoconnor:~/Desktop$ cat ~/.vnc/xstartup.bak #!/bin/sh xrdb "$HOME/.Xresources" xsetroot -solid grey #x-terminal-emulator -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" & #x-window-manager & # Fix to make GNOME work export XKL_XMODMAP_DISABLE=1 /etc/X11/Xsession

Make the file executable and restart the VNC server

chmod +x ~/.vnc/xstartup vncserver -localhost

On the Mac Command Shift to bring up Spotlight Search and search for Screen Share.

Click Share Screen and enter the user name and password.

Alternatively you can do Control K on the Mac desktop background and screen share this way:

Here's the Ubuntu Linux screen share on the Mac,

Ubuntu Apps

Ubuntu comes with Thunderbird email among other applications. You can open Ubuntu Software in the Applications folder and search for more.

Install Gnome-Tweaks using the Ubuntu software app (shopping bag icon).

In the Settings you can launch apps upon startup,

Putting Apps on the Dock

Usually you can run an app from the terminal command line, and when it appears on the dock, you can right click its icon, select add to favorites and that will add it permanently to the dock.

But you might have to do this manually for some apps. For example, I downloaded the latest Blender version 3.3.0 for Linux, unpacked the download to create the Blender directory,


Then edit the blender.desktop in the Blender directory to point to the executable in the section Exec and the Blender icon in section Icon.

[Desktop Entry] Name=Blender GenericName=3D modeler ... GenericName[zh_TW]=3D 模型 Comment=3D modeling, animation, rendering and post-production ... Exec=/home/seanoconnor/Desktop/blender-3.3.0-linux-x64/blender %f Icon=/home/seanoconnor/Desktop/blender-3.3.0-linux-x64/blender.svg ... Terminal=false Type=Application Categories=Graphics;3DGraphics; MimeType=application/x-blender;

Copy the file to where Gnome can find it.

cp blender.desktop ~/.local/share/applications/

Launch Blender from the command line,


After Blender comes up, right click on its icon in the dock and select Add to Favorites (you may not have to do this). Now you should see the Blender icon permanently in the dock.

Running CanoScan LiDE 200 Flatbed Scanner

The CanoScan LiDE 200 flatbed scanner is no longer supported on macOS Monterey. But we can install and run it on Ubuntu using advice from Install Canon LiDE 300 / 400 on Ubuntu 18.4

First install the xsane software if you don't already have it:

sudo apt install xsane sudo apt install libsane-common sudo apt install sane-utils

Connect the scanner to a spare USB port on your PC. Run these tests to see if the scanner is connected and if you can scan at all:

sane-find-scanner # sane-find-scanner will now attempt to detect your scanner. If the # result is different from what you expected, first make sure your # scanner is powered up and properly connected to your computer. # No SCSI scanners found. If you expected something different, make sure that # you have loaded a kernel SCSI driver for your SCSI adapter. could not open USB device 0x1d6b/0x0003 at 004:001: Access denied (insufficient permissions) could not open USB device 0x1a2c/0x2124 at 003:003: Access denied (insufficient permissions) could not open USB device 0x093a/0x2533 at 003:002: Access denied (insufficient permissions) found USB scanner (vendor=0x04a9 [Canon], product=0x1905 [CanoScan], chip=GL847) at libusb:003:004 could not open USB device 0x1d6b/0x0002 at 003:001: Access denied (insufficient permissions) could not open USB device 0x1d6b/0x0003 at 002:001: Access denied (insufficient permissions) could not open USB device 0x1d6b/0x0002 at 001:001: Access denied (insufficient permissions) # Your USB scanner was (probably) detected. It may or may not be supported by # SANE. Try scanimage -L and read the backend's manpage. # Not checking for parallel port scanners. # Most Scanners connected to the parallel port or other proprietary ports # can't be detected by this program. # You may want to run this program as root to find all devices. Once you # found the scanner devices, be sure to adjust access permissions as # necessary. scanimage -L device `genesys:libusb:003:004' is a Canon LiDE 200 flatbed scanner # Simple scan to see if you can get an image at all. scanimage --format=png > test.png ; xdg-open test.png

Now run the nifty xsane scanning program which has a GUI. You can set the scanner resolution and color, preview scan, select the area to scan, do a hi-res scan and view the image.

Set Scanner Options - Scanning Preview - Select Area to Scan - Scan - View Scanned Image
Wifi Diagnostics

You can see what's happening with your WiFi communications with these two utilities. The first one is linssid

sudo apt install linssid sudo linssid # Need to use root.
nm-connection-editor # This will show a GUI with your WiFi settings.

Ubuntu Linux on a MacBook Air

This platform is a 2010 original MacBook Air. Follow the excellent Ubuntu Desktop Installation instructions.

Macbook Air

I downloaded the Ubuntu .iso file and created a USB flash drive. I powered up my MacBook with the USB drive inserted, and paused the boot sequence to select the USB drive as the boot drive. Then I installed Ubuntu according to the instructions. During Ubuntu install I select the option to erase the disk.


Well, macOS is Unix, so you get most of what you want out of the box. Note that macOS only supports 64-bit applications. There are also security features which you'll need to work around when running third party apps.

Working Around macOS Security

When you try to run a third party executable, e.g. ClozureCommonLisp, the OS will block it as follows in macOS:

Go to the Settings->Security and Privacy and allow the exe to run:

You can then open the exe:


Developer Tools Mac


macOS X comes with most of the the Unix utilities make, diff, gcc, g++ (the clang equivalent), lldb, etc. already installed. You can install the free Xcode IDE from the Apple App Store

Install the command line tools also:

# You may have to install Xcode command line tools first. xcode-select --install

When you launch Xcode, it may ask you about which additional SDK's you wish to install

XCode Settings for a Command Line App in C++

I'll use my Primpoly app as an example. Create a new XCode project as a command line app in the C++ language. Drag and drop all source code files into the project. Then go to settings and change the locations for the products. XCode file locations XCode file locations

Add a new pre-build copy command to put some lookup tables in the same place as the executable by editing the Scheme XCode scheme

Make sure your source code and other files is in the correct location (not grayed out) XCode source files

The new MacBook Pro is based on a 64-bit ARM CPU design and has a GPU on the same bus. Apple will automatically ask you to install Rosetta, which emulates the Intel CPU instruction set if you open an Intel App. Make sure you compile all source code to native ARM CPU code *.exe binaries, or you'll get a speed hit of 2X as your Intel binary is emulated on the ARM. You can look at info for any App to see if it is Universal (runs on Intel or Apple Silicon), Intel or Apple silicon).


The new macOS now uses zsh instead of bash (Apple Support: Use zsh as the default shell on your Mac) but you can install the latest version of bash and use it as your shell.

Download the Bash source code from Bash from GNU Web Site

Unpack the bash-5.1.tar file, move it to a convenient directory, cd into that directory, then run these commands,

cd /Users/seanoconnor/Desktop/Apps/Bash/bash-5.1 ./configure make sudo make install

This installs bash into both /usr/local/bin and /usr/local/bin:

seanoconnor@Seans-MBP Bash % /usr/local/bin/bash --version GNU bash, version 5.1.0(1)-release (aarch64-apple-darwin21.2.0) Copyright (C) 2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software; you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.

Make the new version of bash your default shell for all terminals. First edit this file and add the new bash path at the top:

sudo vi /etc/shells 1 # List of acceptable shells for chpass(1). 2 # Ftpd will not allow users to connect who are not using 3 # one of these shells. 4 5 /usr/local/bin/bash 6 /bin/bash 7 /bin/csh 8 /bin/dash 9 /bin/ksh 10 /bin/sh 11 /bin/tcsh 12 /bin/zsh

Then change the default shell on the command line and in the Terminal Preferences

seanoconnor:~$ chsh -s /usr/local/bin/bash Changing shell for seanoconnor. Password for seanoconnor:

Close all terminal windows, open a terminal window up again, and check the version

seanoconnor:~$ echo $BASH_VERSION 5.1.0(1)-release

Brew installs other open source software on the Mac. (it's the macOS version of apt-get for Ubuntu Linux).

# Install brew /bin/bash -c "$(curl -fsSL" ==> Next steps: - Run these two commands in your terminal to add Homebrew to your PATH: echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/seanoconnor/.bash_profile eval "$(/opt/homebrew/bin/brew shellenv)" - Run brew help to get started - Further documentation:

Brew will add this last line to your .bash_profile.

eval "$(/opt/homebrew/bin/brew shellenv)"

Remove this line. Instead, integrate brew's path into your Bash Settings

# Update brew to the latest version. brew update --verbose # Error check your installation. You can ignore some of the warnings. brew doctor

Install rsync with brew.

brew install rsync which rsync /opt/homebrew/bin/rsync rsync --version rsync version 3.2.3 protocol version 31 Copyright (C) 1996-2023 by Andrew Tridgell, Wayne Davison, and others. Web site:

Universal Ctags is a successor to Exuberant Ctags. First install Brew. Then install ctags,

brew install --HEAD universal-ctags/universal-ctags/universal-ctags ctags --version Universal Ctags 5.9.0(e00b6627), Copyright (C) 2015 Universal Ctags Team Universal Ctags is derived from Exuberant Ctags. Exuberant Ctags 5.8, Copyright (C) 1996-2023 Darren Hiebert Compiled: Jan 29 2022, 22:45:12

If you have problems, uninstall,

brew uninstall universal-ctags

Then reinstall as above.

Developer Tools Ubuntu Linux

Naturally, you've got all the unix tools or can easily install them using sudo apt-get from the terminal.


To install Universal Ctags on Ubuntu Linux, download several SW tools first, download the source code, build and install

sudo apt-get install git sudo apt install pkg-config sudo apt install pkgconf cd ~ git clone cd ctags ./ ./configure make sudo make install ctags --help

Bash Settings

I'm using the bash shell in preference to the macOS default zsh. Read the Beginner's Guide, Tutorial, and Reference then go to your home directory, and place the bash startup files .bash_login, .bash_logout and .bashrc there.

I have lots of utilties and shortcuts in these scripts. I automatically detect whether I'm on a macOS or Linux system.

#============================================================================= # # FILE NAME # # .bash_profile # # DESCRIPTION # # Unix startup file executed upon log in. If you want to run this file every # time you open a new Terminal window in Linux, you will need to change Gnome # settings as follows: go to Terminal->Preferences->Profiles, create a new profile # Under Command enable Run command as login shell. # # See also install documentation for various apps here: # # # DATE # # 14 Aug 22 # # AUTHOR # # Sean E. O'Connor # #============================================================================= # #------------- Portability ------- # # Try to determine which system we are running on. #----------------------------------------------------------------------------- #--- Set the path #----------------------------------------------------------------------------- # Be sure to put useful scripts and executables into the home bin directory: ~/bin bins="/usr/local/bin:~/bin" # You need to set the hostname to get the correct configuration loaded. # On MacBook, # sudo hostname WhiteHusky" # sudo scutil --set LocalHostName WhiteHusky # sudo scutil --set ComputerName WhiteHusky # sudo scutil --set HostName WhiteHusky # In System Preferences/Sharing change 'Computer Name' to WhiteHusky if it's not already changed. # In your local network configuration, rename the name provided by DHCP. # On Ubuntu Linux, to change the hostname permanently, # hostnamectl set-hostname Gauss # Find out the hostname. In cygwin bash, strip off the trailing \r introduced. # The alternative is to use tr -d '\r' hostname=`python3 -c "import platform; print( platform.node() )" | sed 's/^[ \r\n\t]*$//'` #echo "hostname=|${hostname}|" # Find out which operating system we are running on: macOS, Linux, Windows/Cygwin, etc. uname=`uname -s` #echo "uname=|${uname}|" # macOS. Tested on my MacBook Pro laptop mid-2015 model with Intel x86_64 architecture. if [ "${uname}" == "Darwin" ] ; then platform="macos" # Linux. Tested on my Ubuntu Linux system running on my Cyperpower PC with a 64-bit AMD CPU. elif [ "${uname}" == "Linux" ] ; then platform="linux" # Cygwin. For cygwin 2.2 64-bit on Windows 10 64-bit. Not tested. From elif [ "${uname}" == "CYGWIN_NT-10.0" ] ; then platform="cygwin" else echo "Can't identify OS platform = ${platform}. Exiting .bash_profile" exit 1 fi #echo "Using platform = ${platform}" if [ "${platform}" == "macos" ] ; then py3bin="/Library/Frameworks/Python.framework/Versions/3.10/bin" #echo "Using macOS System Python version path = ${PATH}" # Linux. Tested on my Ubuntu Linux system running on my Cyperpower PC with a 64-bit AMD CPU. elif [ "${platform}" == "linux" ] ; then py3bin="/usr/local/bin:${HOME}/.local/bin" #echo "Using Ubuntu Linux Python version path = ${PATH}" elif [ "${platform}" == "cygwin" ] ; then py3bin="/usr/local/bin" #echo "Using Cygwin Linux Python version path = ${PATH}" fi # Augmented path. PATH="${py3bin}:${bins}:${PATH}" #echo "Augmented path = ${PATH}" if [ "${platform}" == "macos" ] ; then # Not quite the final path -- For macOS, add the path to brew and add export brew's environment variables. # To see help documentation on this, run # /opt/homebrew/bin/brew -h shellenv eval "$(/opt/homebrew/bin/brew shellenv)" fi # CMake tool used for Blender. cmakebin="/Applications/" # Latest version of make and ack. makebin="/usr/local/bin" # Final path. PATH="${HOME}:${makebin}:${cmakebin}:${PATH}" #echo "Final path = ${PATH}" export PATH # On Ubuntu Linux, run the Python virtual environment. if [ "${platform}" == "linux" ] ; then #echo "Linux: set up Python virtual environment for all terminal windows" if [[ -f ~/.VENV/bin/activate ]] ; then source ~/.VENV/bin/activate # This was commented out by conda initialize echo "Entering `python3 -V` virtual environment at ${VIRTUAL_ENV}. Type deactivate to exit." else echo "WARNING: No Python virtual environment on system. Recommend you set one up." fi fi # Make sure Python 3 is installed on your system. Get the version and redirect from stderr to stdout. python_version=`python3 -V 2>&1` # Delete minor versions (numbers after the first dot), and spaces, e.g. Python 3.10.4 => Python3 python_version_stripped=`echo ${python_version} | sed 's/\.[0-9]*//g' | sed 's/[ \r]//g'` #echo "Python version ${python_version} was detected" #echo "stripped version = ${python_version_stripped}" # Check the version and give help. if [ "${python_version_stripped}" != "Python3" ] ; then echo "WARNING: Calling o l d python version ${python_version} stripped ${python_version_stripped} from `which python` in path $PATH" fi # Default settings. ls_color_option="-G" desk_dir="${HOME}/Desktop" thumb_dir="/Volumes/ALNILAM" extra_bin_path="/usr/local/bin" #------------- Export base directories for use by other programs ------------- # The root directory has /Sean under it and /Sean/WebSite underneath that. export desk_dir export thumb_dir #echo "Root dir |${desk_dir}|, thumb dir |${thumb_dir}|, desk_dir |${desk_dir}|" #------------- Directory Shorthands ------------- # Top level directories sean_dir="${desk_dir}/Sean" app_dir="${desk_dir}/App" export sean_dir export app_dir # Level 1 directories. arts_dir="${sean_dir}/Arts" business_dir="${sean_dir}/Business" family_dir="${sean_dir}/Family" science_dir="${sean_dir}/Sciences" web_dir="${sean_dir}/WebSite" export arts_dir export business_dir export family_dir export science_dir export web_dir # Quickly cd to subdirectories by typing cd subdir. # Need . in the list to avoid having to put ./ in front of directories. export CDPATH=.:~:${sean_dir}:${pp_src_dir} # Mac system tweaks. if [ "${platform}" == "macos" ] ; then # Show hidden files in finder (needs a relaunch of finder). defaults write AppleShowAllFiles TRUE # Screen shots are smaller JPG image files instead of PNG image files. defaults write type jpg fi # Finish up the aliases. source .bashrc #echo "Bash version = ${BASH_VERSION}" # # >>> conda initialize >>> # # !! Contents within this block are managed by 'conda init' !! # __conda_setup="$('/Users/seanoconnor/miniforge3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)" # if [ $? -eq 0 ]; then # eval "$__conda_setup" # else # if [ -f "/Users/seanoconnor/miniforge3/etc/profile.d/" ]; then # . "/Users/seanoconnor/miniforge3/etc/profile.d/" # else # export PATH="/Users/seanoconnor/miniforge3/bin:$PATH" # fi # fi # unset __conda_setup # # <<< conda initialize <<<
#---------------------------------------------------------------------------- # # TITLE # # .bashrc # # DESCRIPTION # # # Bourne Again Shell (bash) startup file for Unix systems. Executed # everytime we start a subshell. Install into your home directory ~. # Put aliases and functions here. # # Use source .bashrc to reset the environment after you are in a # terminal window. Place the line "source .bashrc" into .bash_profile # to execute this file's commands upon login. # # To debug, use sh -x .bashrc # # DATE # # 18 Feb 22 # # AUTHOR # # Sean E. O'Connor # #---------------------------------------------------------------------------- #------------- Aliases ------------- # # Be sure to put useful scripts and executables into the home bin directory, ~/bin or global /usr/local/bin # alias desk='cd ${desk_dir}' alias sean='cd ${sean_dir}' alias app='cd ${app_dir}' alias art='cd ${arts_dir}/Visual/Painting/OriginalWorks' alias bus='cd ${business_dir}' alias fam='cd ${family_dir}' alias sci='cd ${science_dir}' alias math='cd ${science_dir}/Mathematics' alias comp='cd ${science_dir}/ComputerScience' alias acc='cd ${business_dir}/Accounts' alias web='cd ${web_dir}' alias wd='cd "${web_dir}/WebPageDesign"' alias mw='cd ${web_dir}/WebPageDesign/MaintainWebPage' alias priv='cd ${web_dir}/private' alias artw='cd ${web_dir}/Art' alias crc='cd ${web_dir}/CommunicationTheory/ChannelCoding/Crc' alias lif='cd ${web_dir}/ComputerScience/Automata/Life' alias com='cd ${web_dir}/ComputerScience' alias lis='cd ${web_dir}/ComputerScience/Compiler/ParserGeneratorAndParser/SourceCode/ParserGenerator' pp_dir="${web_dir}/Mathematics/AbstractAlgebra/PrimitivePolynomials" pp_proj_dir="${pp_dir}/Project" pp_bld_dir="${pp_dir}/Project/Build" pp_src_dir="${pp_dir}/Project/SourceCode" pp_exe_dir="${pp_bld_dir}/Bin" alias pp='cd ${pp_dir}' alias ppb='cd ${pp_bld_dir}' alias pps='cd ${pp_src_dir}/Primpoly' alias ppsc='cd ${pp_src_dir}/PrimpolyC' # Other directories. #------------- Git ------- # Location of git repository. export GITREPOS="${web_dir}/private/repos" #------------- Set prompt ------- # # Define colors for the text in a prompt. # startcolor="\[\e[" black="30" red="31" green="32" yellow="33" blue="34" magenta="35" teal="36" white="37" separator=";" blackbackground="40" redbackground="41" greenbackground="42" yellowbackground="43" bluebackground="44" magentabackground="45" tealbackground="46" whitebackground="47" reset="0" boldtext="1" underline="4" blink="5" inverted="7" endcolor="m\]" resetcolor="\e[0m" whiteonblue="${startcolor}${white}${separator}${bluebackground}${endcolor}" redonblue="${startcolor}${red}${separator}${bluebackground}${endcolor}" # Set the prompt to # time \@, date \d, user name \u, host name \h, current directory \w # \W basename of current directory, \$ if UID = 0 (root), use # instead of $ export PS1="${redonblue}\u:${whiteonblue}\w${resetcolor}\$ " ###echo ${PS1} #------------- Shell options ------------- # # Set vi edit mode for the command line. # Hit <ESC> to go into vi's edit command mode: # h Move cursor left # l Move cursor right # A Move cursor to end of line and put in insert mode # 0 (zero) Move cursor to beginning of line (doesn't put in insert mode) # i Put into insert mode at current position # a Put into insert mode after current position # dd Delete line (saved for pasting) # D Delete text after current cursor position (saved for pasting) # p Paste text that was deleted # j Move up through history commands # k Move down through history commands # u Undo set -o vi # Don't wait for job termination notification set -o notify # Don't use ^D to exit set -o ignoreeof # Use case-insensitive filename globbing shopt -s nocaseglob # Make bash append rather than overwrite the history on disk shopt -s histappend # When changing directory small typos can be ignored by bash # for example, cd /vr/lgo/apaache would find /var/log/apache shopt -s cdspell shopt -s cdable_vars #------------- Completion options ------------- # # These completion tuning parameters change the # default behavior of bash_completion: # Define to avoid stripping description in --option=description of './configure --help' COMP_CONFIGURE_HINTS=1 # Define to avoid flattening internal contents of tar files COMP_TAR_INTERNAL_PATHS=1 # If this shell is interactive, turn on programmable completion enhancements. # Any completions you add in ~/.bash_completion are sourced last. case $- in *i*) [[ -f /etc/bash_completion ]] && . /etc/bash_completion ;; esac #------------- History options ------------- # # Don't put duplicate lines in the history. export HISTCONTROL="ignoredups" # Ignore some controlling instructions export HISTIGNORE="ls:ls *:[ ]*:&:cd:cd ..:exit:hi:s:f:m:um" # Whenever displaying the prompt, write the previous line to disk export PROMPT_COMMAND="history -a" #------------- Aliases ------------- # # If these are enabled they will be used instead of any instructions # they may mask. For example, alias rm='rm -i' will mask the rm # application. # # To override the alias instruction use a \ before, ie # \rm will call the real rm not the alias. # # To see all aliases, type alias. # Use unalias to remove a definition. # Interactive operation... alias rm='rm -i' alias cp='cp -i' alias mv='mv -i' alias up='cd ..' # Default to human readable figures alias df='df -h' alias du='du -hac' # Misc :) alias less='less -r' # raw control characters alias whence='type -a' # where, of a sort alias grep='grep --color' # show differences in colour alias hi=history # Some shortcuts for different directory listings alias ls='ls -hF ${ls_color_option}' alias dir='ls --color=auto --format=vertical' alias ll='ls -l' # long list alias la='ls -A' # all but . and .. alias l='ls -CF' # #------------- Utility functions ------------- # Recursive search for a string in a file. function grepall() { if [ $# == 0 ] then echo "Usage: grepall <string>" fi # Grab the function argument, bash style. pat=$1 echo "Searching all subdirectories for pattern ${pat}" find . -name '*.[ch]' -exec grep -iH "${pat}" {} ';' find . -name '*.hpp' -exec grep -iH "${pat}" {} ';' find . -name '*.cpp' -exec grep -iH "${pat}" {} ';' find . -name '*.py' -exec grep -iH "${pat}" {} ';' find . -name '*.lsp' -exec grep -iH "${pat}" {} ';' find . -name '*.m' -exec grep -iH "${pat}" {} ';' find . -name '*.js' -exec grep -iH "${pat}" {} ';' find . -name '*.java' -exec grep -iH "${pat}" {} ';' find . -name '*.pl' -exec grep -iH "${pat}" {} ';' find . -name '*.prl' -exec grep -iH "${pat}" {} ';' find . -name '*.html' -exec grep -iH "${pat}" {} ';' find . -name '*.css' -exec grep -iH "${pat}" {} ';' find . -name 'makefile' -exec grep -iH "${pat}" {} ';' find . -name '*.dat' -exec grep -iH "${pat}" {} ';' find . -name '*.txt' -exec grep -iH "${pat}" {} ';' } function touchall() { find . -exec touch {} ';' } function testOptions() { if [ $# == 0 ] then echo "Number of arguments to testOptions is $#" fi # No spaces around the equals allowed in bash! a1=$1 echo "You said |${a1}|" # Compare the first 3 letters. if [ "${a1:0:3}" == "tes" ] then echo "You said testOptions tes" else echo "What did you say?" fi } # Launch gvim editor. function gvim() { # No file name given? if [ $# == 0 ] then # Remove the old file. fileName="${HOME}/temp.txt" if [ -f "${fileName}" ] ; then echo "Removing file ${fileName}" rm -rf ${fileName} fi # Remove any swap file. fileNameSwap="${HOME}.vim/.swp/temp.txt.swp" if [ -f "${fileNameSwap}" ] ; then echo "Removing swap file ${fileNameSwap}" rm -rf ${fileNameSwap} fi # Create a new file. echo -n > ${fileName} echo "Opening temporary file ${fileName}" else fileName=$1 fi # Find out which operating system we are running on: macOS, Linux, Windows/Cygwin, etc. uname=`uname -s` # macOS. Tested on my MacBook Pro laptop mid-2015 model with Intel x86_64 architecture. if [ "${uname}" == "Darwin" ] ; then platform="macos" # Linux. Tested on my Ubuntu Linux system running on my Cyperpower PC with a 64-bit AMD CPU. elif [ "${uname}" == "Linux" ] ; then platform="linux" # Cygwin. For cygwin 2.2 64-bit on Windows 10 64-bit. Not tested. From elif [ "${uname}" == "CYGWIN_NT-10.0" ] ; then platform="cygwin" fi #echo "Using platform = ${platform}" # Launch GUI Vim on my macOS machine. if [ "${platform}" == "macos" ] ; then open -a MacVim "${fileName}" # Launch GUI Vim on my Ubuntu Linux machines. elif [ "${platform}" == "linux" ] ; then /usr/bin/gvim "${fileName}" # Cygwin elif [ "${platform}" == "cygwin" ] ; then /usr/bin/gvim "${fileName}" else echo "Could not get a platform. Guessing Linux." /usr/bin/gvim "${fileName}" fi } # Remove temporary files. function cleanall() { if [ $# != 0 ] then echo "Usage: cleanall" fi find . -name '*~' -print -exec rm -f {} \; find . -name '._*' -print -exec rm -f {} \; find . -name '.DS_Store*' -print -exec rm -f {} \; find . -name 'Thumbs.db' -print -exec rm -f {} \; find . -name '*.swp' -print -exec rm -f {} \; find . -name '*.o' -print -exec rm -f {} \; find . -name '*.class' -print -exec rm -f {} \; find . -name '*.o~$' -print -exec rm -f {} \; find . -name '*.o~>' -print -exec rm -f {} \; find . -name '*.dSYM' -print -exec rm -rf {} \; find . -name '*.obj' -print -exec rm -rf {} \; find . -name '*.ncb' -print -exec rm -rf {} \; find . -name '*.suo' -print -exec rm -rf {} \; find . -name '*.idb' -print -exec rm -rf {} \; find . -name '*.pdb' -print -exec rm -rf {} \; find . -name '*.manifest' -print -exec rm -rf {} \; find . -name '*.Spotlight-V100' -print -exec rm -rf {} \; find . -name '*.Trash*' -print -exec rm -rf {} \; find . -name '*.fseventsd' -print -exec rm -rf {} \; }
#============================================================================= # # FILE NAME # # .bash_logout # # DESCRIPTION # # bash shell executed upon logout. # Install into your home directory ~. # # DATE # # 30 Sep 22 # # AUTHOR # # Sean E. O'Connor # #============================================================================= # # Clean up history. # rm -f ~/.bash_history #rm -f ~/.viminfo # When leaving the console clear the screen to increase privacy if [ "$SHLVL" = 1 ]; then [ -x /usr/bin/clear_console ] && /usr/bin/clear_console -q fi


I use Git for source code control. It's out of the box in macOS and you can install in Ubuntu Linux using

sudo apt install git

It's described in the Git Pro 2 Book. Here's an example of how I set up my Git repository for my Primpoly project using local repositories.

Git Configuration

In your home directory ${HOME}, create the global git configuration file .gitconfig

[user] # Identify me as a user on git. email = name = Sean E. O'Connor [core] # I use the Vim editor. editor = vim excludesfile = /Users/seanoconnor/.gitignore_global [merge] # I use Apple opendiff. tool = opendiff conflictstyle = diff3 [difftool] prompt = false # Don't prompt the user to hit RETURN before the next file difference. [difftool "opendiff"] # cmd = echo 'base(ancestor base for the merge) = ' \"$BASE\" 'local(file on current branch) #= ' \"$LOCAL\" 'remote(file to be merged) = ' \"$REMOTE\" 'merged(what mergetool should write) = ' \"$MERGED\" cmd = opendiff \"$LOCAL\" \"$REMOTE\" -merge \"$MERGED\" [mergetool "opendiff"] cmd = opendiff \"$LOCAL\" \"$REMOTE\" -ancestor \"$BASE\" -merge \"$MERGED\" trustExitCode = true [push] default = simple [credential] helper = cache [alias] # Custom shorthands for commands. unstage = reset HEAD -- uncheckin = checkout -- [difftool "sourcetree"] cmd = opendiff \"$LOCAL\" \"$REMOTE\" path = [mergetool "sourcetree"] cmd = /Applications/ \"$LOCAL\" \"$REMOTE\" -ancestor \"$BASE\" -merge \"$MERGED\" trustExitCode = true [commit] template = /Users/seanoconnor/.stCommitMsg
and which files to ignore globally by git,
# .gitignore_global # # The file types which Git should ignore, i.e. not be added to the repository. # Vim backup files. *~ *.swp # Mac OS X file manager configuration files. .DS_Store # PyCharm project directories. .idea # All Ctags files. tags # HTML versions of LISP, Python, C, C++ files since these are autogenerated by *.lsp.html *.c.html *.h.html *.cpp.html *.hpp.html *.py.html
Local Protocol for the Git Repository

Create a local directory to serve as the Git repository. This is the simplest possible remote protocol, and can be used if you are on a single computer or everyone remotely shares your directory.

cd ${web_dir} cd private mkdir repos cd repos

In your .bashrc file in home directory, add the location of the local git repository,

# Location of git repository. export GITREPOS="${web_dir}/private/repos"

Let's add a new project Primpoly to the remote directory. The --bare flag says there are no files in this directory; it is only used as a central repository to push and pull from local working directories.

$ mkdir Primpoly $ cd Primpoly $ git --bare init Initialized empty Git repository in $web_dir/private/repos/Primpoly/ $ la HEAD branches/ config description hooks/ info/ objects/ refs/
Set up a Local Git Snapshot

Let's place a collection of C++ source files under source code control. This will create a new .git subdirectory.

$ cd ${web_dir}/Mathematics/AbstractAlgebra/PrimitivePolynomials/Project/SourceCode/Primpoly $ git init Initialized empty Git repository in /Users/seanoconnor/Desktop/Sean/WebSite/Art/.git/ $ ls .git HEAD config description hooks/ info/ objects/ refs/

Add the files to source code control.

cd ${web_dir}/Mathematics/AbstractAlgebra/PrimitivePolynomials/Project/SourceCode/Primpoly $ git add *.cpp *.h /FactorTables $ git status On branch master Initial commit Changes to be committed: (use "git rm --cached <file>..." to unstage) new file: FactorTables/c02minus.txt ... new file: FactorTables/c12plus.txt new file: Primpoly.cpp ... new file: ppUnitTest.h Untracked files: (use "git add <file>..." to include in what will be committed) Primpoly.cpp.html ... ppUnitTest.h.html

Your files are staged now. When ready, do a commit,

$ git commit -m "Initial import from SVN." [master (root-commit) 75fa9b1] Initial import from SVN. 32 files changed, 46548 insertions(+) create mode 100755 FactorTables/c02minus.txt ... create mode 100755 FactorTables/c12plus.txt create mode 100755 Primpoly.cpp ... create mode 100755 ppUnitTest.h

You can see your new branch and the history,

git branch * master $ git log commit 75fa9b1ef5b995c178e264d197c413f395221e4d Author: Sean E. O'Connor Date: Sun Aug 14 20:19:22 2016 -0700 Initial import from SVN.
Set up the Remote Repository

Now we let the local directory Primpoly know about the remote repository.

$ git remote add origin $GITREPOS/Primpoly/ $ git remote show origin $ git remote -v origin ${web_dir}/private/repos/Primpoly/ (fetch) origin ${web_dir}/private/repos/Primpoly/ (push)

Then we push up to the remote repository for the first time.

$ git push --set-upstream origin master Counting objects: 35, done. Delta compression using up to 8 threads. Compressing objects: 100% (35/35), done. Writing objects: 100% (35/35), 1.10 MiB | 0 bytes/s, done. Total 35 (delta 2), reused 0 (delta 0) To $GITREPOS/Primpoly/ * [new branch] master -> master

Verify the git repository is set up correctly by doing a test clone from the remote repository, and verify there are no differences between it and your local repository,

$ cd ~/Desktop $ git clone $GITREPOS/Primpoly Cloning into 'Primpoly'... done. $ diff -r ~/Desktop/Primpoly \ ~/Desktop/Sean/WebSite/Mathematics/AbstractAlgebra/ PrimitivePolynomials/Project/SourceCode/Primpoly

You can use macOS X mergetool/opendiff to resolve conflicts.

$ git mergetool

You can rsync the git repository and local files between macOS and Ubuntu Linux If you copy from macOS to Linux, the local git configuration file will point to the macOS home dir instead of the Linux home dir.

cat .git/config ... [remote "origin"] url = /Users/seanoconnor/Desktop/Sean/WebSite/private/repos/ParserGenerator/ ...

You can use a symbolic link to fix that by pointing Linux to the macOS type home directory.

cd ~ sudo ln -s home Users

You may also see the local files say they are changed. Just git restore them and pull again.

git status On branch master Your branch is up to date with 'origin/master'. Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git restore ..." to discard changes in working directory) modified: Primpoly.c modified: Primpoly.h modified: ppArith.c modified: ppFactor.c modified: ppHelperFunc.c modified: ppIO.c modified: ppOrder.c modified: ppPolyArith.c git restore *.c git restore *.h git pull git status On branch master Your branch is up to date with 'origin/master'. nothing to commit, working tree clean


Get a new version of make which you can download. To install, do the usual GNU procedure,

cd /Users/seanoconnor/Desktop/Apps/Make/make-4.3 ./configure make sudo make install make --version GNU Make 3.81 Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. This program built for i386-apple-darwin11.3.0


Download a new version of rsync. Unpack rsync-3.2.3.tar.gz file.

See the rsync INSTALL file for hints on how to install the missing libraries and/or how to generate (or fetch) man pages.

sudo apt install libxxhash-dev sudo apt install libzstd-dev sudo apt install liblz4-dev sudo apt install libssl-dev

Then configure, build and install rsync and check the version.

cd rsync-3.2.3/ ./configure make sudo make install which rsync /usr/local/bin/rsync rsync -v rsync version 3.2.3 protocol version 31


ack does regular expression searches of files within directories recursively. Think of it as fast replacement for combining find and grep with more powerful (Perl style REs) and lots of ways to customize searches.

For example, here are the old and new ways:

find . -name '*.html' -exec grep -H "ack.*html" {} \; ./ComputerScience/macLinuxComputerSetupForDevelopers.html: seanoconnor:~/Desktop/Sean/WebSite$ ack --html "find.*html.*grep" ack --html "ack.*html" ComputerScience/macLinuxComputerSetupForDevelopers.html 1282: seanoconnor:~/Desktop/Sean/WebSite$ ack --html "find.*html.*grep" ack --thpppt _   /| \'o.O' =(___)=    U ack --thpppt!

I downloaded the single Perl file version of ack then made it available to where my PATH could find and run it,

mv ack-v3.5.0 ack chmod +x ack sudo mv ack /usr/local/bin


C++ Language and Compilers

Start by reading the textbooks A Tour of C++ by Bjarne Stroustrup and The C++ Programming Language, 4th Edition then read the latest updates in the C++ Super-FAQ and the C FAQ

Photo of Bjarne Stroustrup.

Mac OS X development tools contain the clang C++ and C compilers. They come with Xcode.

Ubuntu Linux To get C++ and C working in Ubuntu Linux, you can use g++ which is installed already. Or you can install clang, but you have to explicity install its libraries,

sudo apt-get install clang sudo apt-get install libc++-dev sudo apt-get install libc++abi-dev

Then you can compile thus:

$ cat foo.cpp #include <string> #include <iostream> using namespace std; int main(int argc,char** argv) { string s(argv[0]); cout <<s <<endl; } $ clang++ -std=c++11 -stdlib=libc++ foo.cpp

If that doesn't work (but it should), change your makefiles by replacing the default library -stdlib=libc++, with the older GNU library -stdlib=libstdc++

# This is OK if we switch to the older GNU library. $ clang++ -std=c++11 -stdlib=libstdc++ foo.cpp

C++ GUIs

I haven't tried them yet but the C++ GUIs FoxTookit and WxWidgets sound interesting. WxWidgets looks a lot like Windows API with classes. Here is a tutorial ending up with source code for a tetris game.

LLDB Debugger

I use the lldb debugger in the llvm toolchain which comes installed on macOS.

# Load executable compiled with -g option. lldb Bin/Primpoly.exe (lldb) target create "Bin/Primpoly.exe" Current executable set to 'Bin/Primpoly.exe' (x86_64). # Set a breakpoint in the code. (lldb) b ppBigInt.cpp:433 Breakpoint 2: where = Primpoly.exe`BigInt::operator unsigned long() const + 18 at ppBigInt.cpp:433, address = 0x000000010000fa92 # Run the program. (lldb) run 2 4 Process 49251 launched: '/Users/seanoconnor/Desktop/Sean/WebSite/Mathematics/AbstractAlgebra/ PrimitivePolynomials/Project/Build/Bin/Primpoly.exe' (x86_64) Primpoly Version 16.2 - A Program for Computing Primitive Polynomials. Copyright (C) 1999-2023 by Sean Erik O'Connor. All Rights Reserved. ... Process 49251 stopped * thread #1: tid = 0x8a8db2, 0x000000010000fa92 Primpoly.exe` BigInt::operator unsigned long(this=0x00007fff5fbf8d18) const + 18 at ppBigInt.cpp:433, queue = '', stop reason = breakpoint 2.1 frame #0: 0x000000010000fa92 Primpoly.exe`BigInt::operator unsigned long (this=0x00007fff5fbf8d18) const + 18 at ppBigInt.cpp:433 430 BigInt::operator ppuint() const 431 throw( BigIntOverflow, bad_exception ) 432 { -> 433 ppuint result = 0 ; 434 ppuint b = base_() ; 435 436 for (int i = static_cast<unsigned int> digit_.size()) - 1 ; i > 0 ; --i) # Backtrace (lldb) bt * thread #1: tid = 0x8a8db2, 0x000000010000fa92 Primpoly.exe `BigInt::operator unsigned long(this=0x00007fff5fbf8d18) const + 18 at ppBigInt.cpp:433, queue = '', stop reason = breakpoint 2.1 * frame #0: 0x000000010000fa92 Primpoly.exe`BigInt::operator unsigned long (this=0x00007fff5fbf8d18) const + 18 at ppBigInt.cpp:433 frame #1: 0x00000001000dc1b9 Primpoly.exe`unitTest() + 16233 at ppUnitTest.cpp:641 frame #2: 0x0000000100000c89 Primpoly.exe`main(argc=3, argv=0x00007fff5fbff600) + 89 at Primpoly.cpp:162 frame #3: 0x00007fff934cd5ad libdyld.dylib`start + 1 # Step to next line. (lldb) n Process 49251 stopped * thread #1: tid = 0x8a8db2, 0x000000010000fa9d Primpoly.exe `BigInt::operator unsigned long(this=0x00007fff5fbf8d18) const + 29 at ppBigInt.cpp:434, queue = '', stop reason = step over frame #0: 0x000000010000fa9d Primpoly.exe`BigInt::operator unsigned long(this=0x00007fff5fbf8d18) const + 29 at ppBigInt.cpp:434 431 throw( BigIntOverflow, bad_exception ) 432 { 433 ppuint result = 0 ; -> 434 ppuint b = base_() ; 435 436 for (int i = static_cast<unsigned int> digit_.size()) - 1 ; i > 0 ; --i) 437 { # List breakpoints. (lldb) br l Current breakpoints: 1: file = 'ppBigInt.cpp', line = 433, locations = 1, resolved = 1, hit count = 1 1.1: where = Primpoly.exe`BigInt::operator unsigned long() const + 18 at ppBigInt.cpp:433, address = 0x000000010000fa92, resolved, hit count = 1 2: name = 'l', locations = 0 (pending) 3: name = 'list', locations = 0 (pending) 4: name = 'l', locations = 0 (pending) # Delete all breakpoints. (lldb) br del About to delete all breakpoints, do you want to do that?: ÆY/nÅ y All breakpoints removed. (4 breakpoints) # Print a value. (lldb) p digit_ (std::__1::vector<unsigned long, std::__1::allocator< unsigned long> >) $4 = size=4 { [0] = 4 [1] = 3 [2] = 2 [3] = 1


Keep the tutorial and library reference handy. Or better yet, download the whole set.

If you program LISP already, Python is very similar.

Python on MacOS

On macOS don't use the shipping python. Go to the Python Web Site and download the latest version of Python.

Python 3 installs into /Library/Frameworks/Python.framework/Versions/3.10 The installer will prefix the Python 3 path to your existing path in your .bash_profile

# Setting PATH for Python 3 # The original version is saved in .bash_profile.pysave PATH="/Library/Frameworks/Python.framework/Versions/3.10/bin:${PATH}" export PATH

I don't like this so remove it and set up a custom .bash_profile to change the path in cleaner manner.

Check by running the command python3 -V that we call Python 3.10

For Python 3.10.x, install SSL root certificates, if you haven't already done so during the install,

pip3 install certifi

Get the latest PIP and check the version.

python3 -m pip install --upgrade pip pip3 --version pip 22.2.2 from /Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/pip (python 3.10)

Installing a virtual environment.

pip3 install virtualenv

Create a virtual environment which uses Python 3.x in your home directory. Remove any old virtual environments first. This will create a hidden subdirectory .VENV.

cd rm -rf .VENV/ virtualenv -p python3.10 .VENV

Activate it. You’ll get a command line prompt showing you are in the virtual environment with the version of Python you chose.

source ~/.VENV/bin/activate (.VENV) seanoconnor:~$ python -V Python 3.10.6

For convenience, go into macOS Terminal ➤ Preferences ➤ Profiles to launch the virtual environment for the Ocean window profile.

To uninstall your Python virtual environment,

pip3 uninstall virtualenv
Python on Ubuntu Linux

On Ubuntu Linux install Python.

sudo apt install python3 sudo apt update

Install pip using

python3 -m pip install --upgrade pip

Install the virtual environment,

sudo apt install python3-virtualenv cd ~ virtualenv -p python3 .VENV

To enable the virtual environment in a terminal window, do this command,

source ~/.VENV/bin/activate (.VENV) seanoconnor:~$ python -V seanoconnor:~$ python -V Python 3.10.4 seanoconnor:~$ pip --version pip 22.0.2 from /home/seanoconnor/.VENV/lib/python3.10/site-packages/pip (python 3.10)

Deactivate the virtual envionment using

(.VENV) seanoconnor:~$ deactivate

For Python 3.x, install SSL root certificates, and install numpy, matplotlib, and other useful packages. See installing Python packages below for details.

Similarly to setting up .bash_profile for Python in macOS edit the code in your .bash_profile to set the path to Python 3.x On my Ubuntu Linux I've wired the bash profile script to automatically launch each new instance of terminal window in the Python virtual environment.

Installing Python Packages

You might as well upgrade pip then install every Python math library you need,

pip3 install --upgrade pip pip install certifi # Python HTTPS certificates. pip install numpy # Vector and array library. pip install scipy # Scientific library pip install sympy # Symbolic math package. pip install ipython # Interactive python shell. See pip install nose # Unit testing utility. See pip install statsmodels # Statistical testing and modeling. See pip install matplotlib # Plotting. pip install pandas # Data analysis. See pip install jupyter # Mathematica-like notebook using Python. pip install jupyterlab # Jupyter notebook improved interface (can debug Python!) pip install opencv-contrib-python # Image processing. pip install imutils # More image processing. pip install scikit-learn # ? pip install pydot # NN plotting utils. pip install autopep8 # Python code formatter.

Keras and TensorFlow are optional.

pip install keras # Neural Net front end. pip install tensorflow # TensorFlow Neural Net architecture. (This will take a while).

You can verify which PIP modules you have installed:

(.VENV) seanoconnor:~$ pip3 list | grep -e numpy -e scipy numpy 1.23.2 scipy 1.9.1

If you are using a virtual environment, go into the VENV and do the pip upgrade and install all packages again, since you are in a separate sandbox, so to speak.

source ~/.VENV/bin/activate (.VENV) seanoconnor:~$ pip3 install --upgrade pip (.VENV) seanoconnor:~$ pip3 install numpy scipy sympy ipython nose statsmodels matplotlib pandas jupyter jupyterlab opencv-contrib-python imutils scikit-learn pydot autopep8

Here is a Python source code formatter. For example, I reformatted my web tool as follows:

autopep8 --in-place --aggressive --aggressive

I use the free community edition of PyCharm IDE on my Apple Silicon M1 MacBook Pro.

To create a new project from an existing file do File->Open and select the file.

I'm assuming you've set up a Python virtual environment. PyCharm should show it in the Settings:

Edit the configuration to put in command line arguments for your script.


  • You need to define a main() function or PyCharm won't run.
  • If you get the error saying the SDK cannot be written to, try deleting all the Python interpreters in the list except the one you are using.
  • You can format the source code to the Python PEP standard!

You can do source level debugging in the IDE and code inspection and refactoring.

Debugging Python on the Command Line

In this example, we use my program The program has been set up to either run from the command line or as a module.

if __name__ == '__main__': """Python executes all code in the file, so all classes and functions get defined first. Finally we come here. If we are executing this file as a Python script, the name of the current module is set to main, thus we'll call the main() function.""" main() else: """When using as a module, start python, then import the module and call it: python import updateweb updateweb.main(["--test"]) Or if you want to debug, do this: python import pdb import updateweb'updateweb.main(["--test"])') b updateweb.main c """ pass

Run Python and import the debugger module, and the entire script itself

seanoconnor:~/Desktop/Sean/WebSite/WebDesign/MaintainWebPage$ python Python 3.9.3 (v3.9.3:e723086bc3, Apr 2 2021, 08:25:55) [Clang 6.0 (clang-600.0.57)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import pdb >>> import updateweb

Set up the debugger to run starting in the main() function with arguments,


Set a breakpoint in main

(Pdb) b updateweb.main Breakpoint 1 at /Users/seanoconnor/Desktop/Sean/WebSite/WebDesign/MaintainWebPage/

Start running the program. We stop at the breakpoint,

(Pdb) c > /Users/seanoconnor/Desktop/Sean/WebSite/WebDesign/MaintainWebPage/ -> print("""

List the source lines around the breakpoint

(Pdb) l 553 554 B def main(raw_args=None): 555 """Main program. Clean up and update my web site.""" 556 557 # Print the obligatory legal notice. 558 -> print(""" 559 updateweb Version 5.8 - A Python utility program which maintains my web site. 560 Copyright (C) 2007-2023 by Sean Erik O'Connor. All Rights Reserved. 561 562 It deletes temporary files, rewrites old copyright lines and email address 563 lines in source files, then synchronizes all changes to my web sites. (Pdb)

Print a variable

(Pdb) p raw_args ['--test']

Backtrace shows the calling stack,

(Pdb) bt /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/ -> exec(cmd, globals, locals) (1)() > /Users/seanoconnor/Desktop/Sean/WebSite/WebDesign/MaintainWebPage/ -> CommandLineSettings(user_settings, raw_args )

See (Pdb) help and the Online Python Manual for more information.

Common Lisp

LISP is always ten years ahead at any given time.

Ubuntu Linux

sudo apt-get install sbcl

Macs Download the install package for the binary from Steel Bank Common Lisp. Unpack and follow instructions.

cd ~/Desktop/Apps/SBCL/sbcl-2.1.2-arm64-darwin sudo sh Password: ... /usr/local make: Entering directory '/Users/seanoconnor/Desktop/Apps/SBCL/sbcl-2.1.2-arm64-darwin/contrib/asdf' SBCL has been installed: binary /usr/local/bin/sbcl core and contribs in /usr/local/lib/sbcl/ Documentation: man /usr/local/share/man/man1/sbcl.1

Once installed, you'll get a bare-bones command line REPL. Try running $ sbcl from the command line and try

(car '(a b c)) (cdr '(a b)) (cons 'a '(b c)) (quit)

You can also run a LISP script from file directly:

cat hello.lsp #!/usr/local/bin/sbcl --script ; Shebang to call the LISP interpreter for this file. ; Do chmod 755 hello.lsp to make the file executable. ; ; hello.lsp ; A simple LISP test program. ; Print a string to the console. (write-line "Hello, World!") ; Convert a LISP list to a string. (defun list-to-string (lis) (format nil "~A" lis)) ; Function which prints a LISP expression and its evaluation to the console. (defun show-example( x ) (write-line (list-to-string `(,x => ,@(eval x))))) ; Print this example: ; (((LAMBDA (X) (1+ X)) 2) => . 3) (show-example '( (lambda(x) (1+ x)) 2) ) (show-example '(defvar dog)) (show-example '(setf dog '(husky))) (show-example 'dog)
./hello.lisp Hello, World! (((LAMBDA (X) (1+ X)) 2) => . 3) ((DEFVAR DOG) => . DOG) ((SETF DOG '(HUSKY)) => HUSKY) (DOG => HUSKY)

For convenience, I load my Common LISP parser generator project in the SBCL startup file .sbclrc

(load "LR(1)AndLALR(1)ParserGenerator.lsp") (load "LR(1)AndLALR(1)Parser.lsp") (test-parser-generator) (test-parser)

However, your life will be much easier if youw download and install Slime Unpack and install the slime directory in /Applications/slime then install this .emacs file in your home directory:

(setq inferior-lisp-program "/usr/local/bin/sbcl") (add-to-list 'load-path "/Applications/slime") (require 'slime) (slime-setup)

Vim, Ctags, Emacs, Slime, Steel Bank Common Lisp.

You should also install Emacs Invoke Emacs and with the command M-x slime go into Lisp interaction mode. Useful REPL commands are Control-c Control-p to move back one prompt, Control-c Control-n to move forward, Control-a and Control-e to go to beginning and end of the line, Control-x o to switch between buffers, Control-C Control-D d to lookup documentation for a symbol, and Control-X Control-S to exit emacs.

For LISP tutorials and references online see

I've also used CLISP


I was programming in Perl and switched over to Python after discovering this article.


The first language I learned was FORTRAN from Bill Joy at U. C. Berkeley!

Berkeley Computing Center Punched card circa 1975.

It now has object oriented programming!

On Ubuntu Linux install GNU Fortran using

sudo apt-get install gfortran

Here's a sample program

$ cat circle.f90 ! A module containing classes. module class_Circle implicit none private real :: pi = 3.1415926535897931d0 ! Module-wide private constant ! Circle class. type, public :: Circle ! Member variable. real :: radius contains ! Member functions defined here but implemented elsewhere in the module. procedure :: area => circle_area procedure :: print => circle_print end type Circle ! Circle member functions implemented here. contains function circle_area( this ) result( area ) class( Circle ), intent( in ) :: this real :: area area = pi * this%radius ** 2 end function circle_area subroutine circle_print(this) class( Circle ), intent( in ) :: this real :: area area = this%area() ! Call the type-bound function print *, 'Circle: r = ', this%radius, ' area = ', area end subroutine circle_print end module class_Circle program circle_test use class_Circle ! Use the classes in the module. implicit none type( Circle ) :: c ! Declare a variable of type Circle. c = Circle( 1.5 ) ! Use the implicit constructor, radius = 1.5. call c%print ! Call the type-bound subroutine end program circle_test

Build it and run it!

$ gfortran circle.f90 -o circle ./circle Circle: r = 1.50000000 area = 7.06858349

Math Software

There are a number of free alternatives to MATLAB and Mathematica for symbolic and matrix computation.


SciPy is a scientific math suite for Python.

Here's how to install on Mac.

python -m pip install --user numpy scipy matplotlib ipython jupyter pandas sympy nose statsmodels

You can list the packages installed using either python -m pip list or pip list.

pip list Package Version ----------------------- cycler 0.10.0 kiwisolver 1.1.0 matplotlib 3.1.2 numpy 1.17.4 pandas 0.25.3 patsy 0.5.1 pip 19.3.1 pyparsing 2.4.5 python-dateutil 2.8.1 pytz 2019.3 scipy 1.3.3 setuptools 42.0.2 six 1.13.0 statsmodels 0.10.2

To uninstall a package, for example, numpy, do

pip uninstall numpy

Here's an example taken from Normality Tests in Python Run python from the command line and type in these commands:

import numpy as np from numpy import mean from numpy import std from matplotlib import pyplot from import qqplot from scipy.stats import shapiro from scipy.stats import normaltest from scipy.stats import anderson # I generated random numbers from a N( 0, 10^2 ) distribution using the Box-Muller-Marsaglia method. NormalDeviatesList = [ -9.594, -6.614, 7.974, 8.959, 26.220, -11.746, -16.308, ... # Map to an np array type. NormalDeviatesArray = np.array( NormalDeviatesList ) # Mean and standard deviation look OK. mean(NormalDeviatesArray) -0.10023199999999999 std(NormalDeviatesArray) 9.95592528857946 # Plot a histogram and QQ plot. pyplot.hist(NormalDeviatesArray) qqplot(NormalDeviatesArray, line='s') # Run a few Normality tests. stat, p = shapiro(NormalDeviatesArray) stat 0.9996619820594788 p 0.5912390351295471 # So failed to the reject Normal hypothesis at 5% level using Shapiro-Wilks test. stat, p = normaltest(NormalDeviatesArray) stat 1.2465252328072989 p 0.5361921912564886 # So again, failed to the reject Normal hypothesis at 5% level using D’Agostino’s K^2 Test. result = anderson(NormalDeviatesArray) print('Statistic: %.3f' % result.statistic) Statistic: 0.350 p = 0 for i in range(len(result.critical_values)): sl, cv = result.significance_level[i], result.critical_values[i] if result.statistic < result.critical_values[i]: print('%.3f: %.3f, data looks normal (fail to reject H0)' % (sl, cv)) else: print('%.3f: %.3f, data does not look normal (reject H0)' % (sl, cv)) 15.000: 0.576, data looks normal (fail to reject H0) 10.000: 0.655, data looks normal (fail to reject H0) 5.000: 0.786, data looks normal (fail to reject H0) 2.500: 0.917, data looks normal (fail to reject H0) 1.000: 1.091, data looks normal (fail to reject H0)

Normal Histogram

QQ Plot


Sympy is a symbolic math package built on top of Python.

Here's how to install on Mac.

First install mpmath by doing

git clone cd mpmath git pull sudo python install
Then install sympy by doing
git clone cd sympy git pull sudo python install
To do plotting, install matplotlib by doing,
python -mpip install -U matplotlib
Test by running Python, importing sympy and running a few commands,
python >>> from sympy import * >>> init_printing() >>> x = Symbol('x') >>> f = Function('f') >>> f = sin(x) >>> diff(f,x) cos(x) >>> integrate(f,x) -cos(x) >>> f.series(x,0,10) x - x**3/6 + x**5/120 - x**7/5040 + x**9/362880 + O(x**10) >>> a = Symbol('a') >>> b = Symbol('b') >>> c = Symbol('c') >>> d = Symbol('d') >>> m = Matrix( [[ a, b] , [c, d] ] ) >>> m ⎡a b⎤ ⎢ ⎥ ⎣c d⎦ >>> m.eigenvals() ⎧ _________________________ _________________________ ⎫ ⎪ ╱ 2 2 ╱ 2 2 ⎪ ⎨a d ╲╱ a - 2⋅a⋅d + 4⋅b⋅c + d a d ╲╱ a - 2⋅a⋅d + 4⋅b⋅c + d ⎬ ⎪─ + ─ - ────────────────────────────: 1, ─ + ─ + ────────────────────────────: 1⎪ ⎩2 2 2 2 2 2 ⎭ >>> m * (m ** -1) ⎡ a⋅d b⋅c ⎤ ⎢───────── - ───────── 0 ⎥ ⎢a⋅d - b⋅c a⋅d - b⋅c ⎥ ⎢ ⎥ ⎢ a⋅d b⋅c ⎥ ⎢ 0 ───────── - ─────────⎥ ⎣ a⋅d - b⋅c a⋅d - b⋅c⎦ >>> simplify( m * (m ** -1)) ⎡1 0⎤ ⎢ ⎥ ⎣0 1⎦

And here's a simple plot,

>>> plot(x**2,(x,-1,1))

Sympy plot( x**2, (x,-1,1))


Octave is a free MATLAB clone.

Run from /Applications. It comes up in a terminal window. In the window, cd to your working directory containing your MATLAB .m files. Type the name of your MATLAB function or type the name of the .m file if you have just an inline main program.


SageMath is a free mathematics software system comparable to Mathematica. You can interact with it using the Jupyter notebook interface. Follow the download instructions. Double click to launch. When you launch it, it will open up a couple of windows in your default web browser. This takes a few minutes, so wait patiently.

I've used it on my primitive polynomial finder


R is a statistical and plotting language.

For the Mac you can Download R as a package. Be sure to check the signature of the *.pkg file before you install it.

pkgutil --check-signature R-3.6.0.pkg Package "R-3.6.0.pkg": Status: signed by a certificate trusted by macOS Certificate Chain: 1. Developer ID Installer: Simon Urbanek (VZLD955F6P) SHA1 fingerprint: 7B 6B 81 12 E6 26 8C 16 F8 D4 ----------------------------------------------- 2. Developer ID Certification Authority SHA1 fingerprint: 3B 16 6C 3B 7D C4 B7 51 C9 FE ----------------------------------------------- 3. Apple Root CA SHA1 fingerprint: 61 1E 5B 66 2C 59 3A 08 FF 58 md5 R-3.6.0.pkg MD5 (R-3.6.0.pkg) = 64ede92058dde6c4e4c2c11e0ba8a60c
Once installed, run on the command line. I found out we can use equals for variable assignment (see below).
R R version 3.6.0 (2019-04-26) -- "Planting of a Tree" Copyright (C) 2019 The R Foundation for Statistical Computing Platform: x86_64-apple-darwin15.6.0 (64-bit) > x = c( 1, 2, 3, 4, 5, 6, 7 ) > var(x) [1] 4.666667 > mean(x) [1] 4 > sum(x) [1] 28 > 2 * x [1] 2 4 6 8 10 12 14
Read Introduction to R


VIM Programmer's Editor

Download gvim from Vim for Mac and Ubuntu Linux. Don't forget the Vim User Manual and tutorial.

Don't forget to define the gvim function in your .bash_profile.

In Ubuntu Linux install gvim like this:

sudo apt-get install vim sudo apt install vim-gtk3

I've customized the Vim GUI in the startup file .vimrc which lives in the home directory ~ on Mac or Ubuntu Linux. Here is my .vimrc

" NAME " " .vimrc " " DESCRIPTION " " Settings for Vim editor loaded upon startup. " " NOTES " " UNIX, macOS: Copy to ~/.vimrc " Windows: Copy to C:/Program Files/vim/_vimrc " " AUTHOR " " Bram Moolenaar &lt;; " Sean E. O'Connor 15 Oct 2020 " " " Use Vim settings, rather then Vi settings (much better!). " This must be first, because it changes other options as a side effect. set nocompatible " Mouse and window behavior tuned for Microslime Windows. behave mswin " Restore Control-F to page forward instead of find dialog box. "unmap&lt;C-F&gt; " Allow backspacing over everything in insert mode. set backspace=indent,eol,start " Turn on backup option. set backup " Create the backup directory if it doesn't exist. if !isdirectory($HOME.'/.vim/.backup') silent call mkdir( $HOME.'/.vim/.backup', 'p' ) endif " Store backups in the home directory ~/.vim/.backup. set backupdir=~/.vim/.backup " Make a backup before overwriting the current buffer. set writebackup " Overwrite the original backup file. set backupcopy=yes " Put swap files in the home directory ~/.vim/.swp if !isdirectory($HOME."/.vim/.swp") silent call mkdir( $HOME.'/.vim/.swp', 'p' ) endif set directory=~/.vim/.swp set history=500 " Keep 500 lines of command line history. set ruler " Show the cursor position all the time. set showcmd " Display incomplete commands. set incsearch " Do incremental searching. set hlsearch " Searches are highlighted. set wildmenu " File name completing using tabs cycles through all possibilities. set lazyredraw " Don't redraw screen while running macros. set lines=60 " Number of lines visible on the screen. set columns=140 " Number of columns visible on the screen. winpos 400 0 " Initial window position (MacBookPro). set winwidth=140 " Initial window width. set winminwidth=140 " set cursorline " Highlight the current line. set number " Show line numbers. set nosmartindent " Don't use smart indenting. set tabstop=4 " Tabs are 4 spaces wide. set softtabstop=4 " When editing, tabs are 4 spaces wide. set shiftwidth=4 " Indent 4 spaces. set expandtab " Expand tabs into spaces. set smarttab set showmatch " Show matching parentheses. set matchtime=5 " Match time is 1/2 sec. " Error blink and bell. set errorbells set visualbell " Set file paths to my most commonly used directories (MacBookPro). set path="~/Applications/vim/**" set path+="~/Desktop/Sean/WebSite/**" " Default directory is my current active subdirectory " in my web page directory. " This is where :e . takes us. cd ~/Desktop/Sean/WebSite/Mathematics/AbstractAlgebra/ PrimitivePolynomials/Project/SourceCode " Set paths for tags files generated by Ctags. See :help tags " "./tags" means search for the file "tags" in the same directory as the current f i l e you are editing. " "tags" means search for the file "tags" in the current working directory (the directory shown by the command :pwd) " NOTE: this is affected if you set autochdir (see below). " Then search from the directory containing tags to your home directory. set tags=./tags,tags;~ " Automatically change the current working directory to the one containing the file which was opened. See :help autochdir "Note: When this option is on some plugins may not work. set autochdir " Color them the same as the C group-name "Type". highlight link xType Type " | Color scheme and font for the full gVim GUI. " | Use the default for launching vim from a command window. if has("gui_running") colorscheme torte " To verify the if condition, on the Vim command line, do " :echo has("x11") " and look for 1 or 0. " " To find out the font type: " In the Vim command line, do " :set guifont=* " to make a menu come up. " " Select the font from the menu. " " Do the command " :set guifont? " to find out the name. " " In the if tests below, add " set guifont=&lt;name of the font&gt; " Escape all spaces with backslashes. " if has("gui_win32") set guifont=Courier_New:h13:b " Test for Mac first. elseif has("mac") set guifont=Menlo\ Regular:h12 " On Ubuntu Linux elseif has("x11") set guifont=Courier_New:h13:b " Otherwise else set guifont=* endif endif " Switch syntax highlighting on, when the terminal has colors. " Also switch on highlighting the last used search pattern. if &t_Co &gt; 2 || has("gui_running") syntax on set hlsearch endif " Abbreviations. My name: :iabbrev soc Sean E. O'Connor " Right arrow. :iabbrev rar &#10148; " Insert html math symbols. map ,th i&lt;em&gt;Theorem.&lt;/em&gt; map ,pf i&lt;em&gt;Proof.&lt;/em&gt; map ,lem i&lt;em&gt;Lemma.&lt;/em&gt; map ,cor i&lt;em&gt;Corollary.&lt;/em&gt; map ,qed i$\blacksquare$ " Insert Blender hotkeys. map ,bprop i&lt;img src="Images/bprop.jpg" alt="Properties Area" width="50" height="25"/&gt; &lt;em class="hotkey"&gt; Properties Area&lt;/em&gt; map ,bren i&lt;img src="Images/bren.jpg" alt="Render Properties" width="50" height="25"/&gt; &lt;em class="hotkey"&gt;Render Properties&lt;/em&gt; map ,bwor i&lt;img src="Images/bwor.jpg" alt="World Properties" width="25" height="25"/&gt; &lt;em class="hotkey"&gt;World Properties&lt;/em&gt; map ,bhot a &lt;em class="hotkey"&gt;&lt;/em&gt;&lt; ESC&gt;4hi " Insert html emphasis. map ,em a &lt;em&gt;&lt;/em&gt;&lt;ESC&gt;4hi " Insert html paragraph. map ,par i&lt;p&gt;&lt;CR&gt;&lt;CR&gt;&lt; /p&gt;&lt;ESC&gt;ki " Insert hyperlink. map ,hr i&lt;a href=""&gt;&lt;/a&gt;&lt;ESC&gt;0f"a " Insert an image. map ,img i&lt;img class="centeredsmaller" src="Images/thingumbob.jpg"& gt;&lt;ESC&gt;4bdwi " Insert a scroll box. map ,sb i&lt;div class="scrollBox"&gt; &lt;div class="scrollBoxContent"&gt;& lt;CR&gt;&lt;CR&gt;&lt;/div&gt;&lt; /div&gt;&lt;ESC&gt;ki " Reload this VIM resource file. map ,sou :source $HOME/.vimrc&lt;CR&gt; " Save the file. map ,sa :w&lt;CR&gt; " Trim blanks at end of all lines. Turn off search highlighting. map ,tbe :%s/\s*$//&lt;CR&gt;&lt;ESC&gt; :nohlsearch&lt;CR&gt;&lt;ESC&gt; " Make p in Visual mode replace the selected text with the "" register. vnoremap p &lt;Esc&gt;:let current_reg = @"&lt;CR&gt; gvs&lt;C-R&gt; =current_reg&lt;CR&gt;&lt;Esc&gt; " Turn off highlighting after searches. map ,&lt;SPACE&gt; :nohlsearch&lt;CR&gt; " Toggle comment lines. You can highlight the range " with the mouse and then type ,to map ,to :call ToggleComment()&lt;CR&gt; function! ToggleComment() " Get the line under the cursor " Check if it begins with | if getline(".") =~ '^|' let s:savedSearchPat=@/ s/^|// let @/=s:savedSearchPat else let s:savedSearchPat=@/ s/^/|/ let @/=s:savedSearchPat endif endfunction " You can highlight lines of text before you call this function which converts angle brackets and ampersands to HTML. map ,ch :call CleanHTML()&lt;CR&gt; function! CleanHTML() s/&/\&amp;/g s/&gt;/\&gt;/g s/&lt;/\&lt;/g endfunction " Convert C comments on a line to C++ comments. map ,cc :call ConvertCCommentToCpp()&lt;CR&gt; function! ConvertCCommentToCpp() " Get the line under the cursor " Check if contains a /* if getline(".") =~ '\/\*' let s:savedSearchPat=@/ s/\/\*/\/\// let @/=s:savedSearchPat endif if getline(".") =~ '\*\/' let s:savedSearchPat=@/ s/\*\/// let @/=s:savedSearchPat endif endfunction " Justify a paragraph. map ,j gqap
Searching Multiple Files in Vim

For example, to search all *.cpp files in the current directory for the word static_cast, do this on the vim command line:

:vimgrep /static_cast/ **/*.cpp :copen 20

You can then go to the line containing the pattern you want and hit return to go to the file.

Searching Patterns in Multiple Files in Vim

Or better yet, you can use ack instead of grep for searches using the ack.vim plugin

File Differences in Vim
To do file differences, load the first file, ignore whitespace with :diffopt=iwhite, then do :diffsplit <second file name>. :diffupdate will resync if needed.

LibreOffice - Free Replacement for Microsoft Office

LibreOffice is free office suite compatible with Microsoft Office. Their apps can replace Excel, Word and PowerPoint. There are also Math and Database apps. LibreOffice apps can read Excel, Word and PowerPoint files, but may not be able to write recent versions of the file format. Say "yes" when the installer asks for permission to install and "yes" when LibreOffice asks to view documents in your directory.


For macOS download an install bundle from the MacTex TeX User's Group,

For Ubuntu Linux install using the install instructions,

sudo apt install texlive-latex-extra

Then try it out on a LaTeX file by processing it to a .pdf

pdflatex MortgageLoanDerivation.tex

View the .pdf file with either

evince MortgageLoanDerivation.pdf


xdg-open MortgageLoanDerivation.pdf

Be sure to read the quickie introduction A (Not So) Short Introduction to LATEX2ε

Art Software

GIMP Paint Program

Similar to Adobe Photoshop with paint tools and layers, but free, GIMP runs on both Mac and Ubuntu Linux download it and its documentation from Gimp


In Ubuntu Linux install with

sudo apt-get install gimp


Blender is a free 3D rendering and animation tool. I have a worked example on my art page.


I use Inkscape to do the drawing and generate SVG files.

To install on Ubuntu Linux,

sudo apt install inkscape

Right click on the Dash, and Add to Favorites


Netzero ISP

I used connect to the internet through the dialup telephone line using Netzero but now I use AT&T Uverse.


On macOS I use the FTP client Transmit. Not free but very easy to use.

On Ubuntu Linux I use the free FTP client FileZilla. which is easily installed,

sudo apt install filezilla

Web Browsers

Download the Firefox, Opera and Chromium browsers. Safari comes with MacOS.

Email Clients

On Ubuntu Linux install Thunderbird email,
sudo apt-get install thunderbird


Install Zoom client for virtual meetings with other humans.

Antivirus for Mac

Install free Avast Antivirus Mac because it's prudent.




Stellarium is a free planetarium program.

On Ubuntu Linux install using
sudo apt install stellarium

Red Pill Screen Saver

Get the source code from GitHub opx3 / RedPill2. You can clone the repository using

git clone

Build in XCode in Release mode. Let XCode update your settings. Double click on RedPill.saver to load it.

Exif Metadata Read/Write Tool

Exiftool lets you view and rewrite metadata in files. For a book in PDF format, the title will be the file name and the author will be read from the metadata. Set the author using the command

exiftool -author="Wald, R" *.pdf


Installing Ubuntu Linux on a 2009 17 Inch MacBook

Too slow to really be useful, but here for fun.

Macbook Macbook

I will install on an old MacBook Pro (17-inch, Early 2009) running OS X El Capitan Version 10.11.6 (15G31).


You can read through these excellent guides on Install Linux on a Mac and how to dual boot Linux and macOS I took a little from both and from the Ubuntu web site documentation.

Installing the Boot Loader

The Mac's own boot manager has problems recognizing the Ubuntu OS. Thus you need to install a third party EFI (Extensible Firmware Interface) boot manager to be able to dual boot the Mac into Ubuntu or macOS. Visit the rEFInd Boot Manager Web Page. Download rEFIfind version

Downloading rEFFind

Disable SIP (System Integrity Protection) so you can install the boot loader. Shut down the Mac for 30 seconds. Then reboot in recovery mode. You can hold down the Option key and select the Recovery Disk. Select Terminal from the OSX Utitities menu bar and type csrutil disable. Then reboot again.

Unzip and install. You'll see I've already installed it once before.rEFInd

Gauss:refind-bin-0.11.2 sean$ sudo ./refind-install ShimSource is none Installing rEFInd on OS X.... Installing rEFInd to the partition mounted at /Volumes/ESP Found rEFInd installation in /Volumes/ESP/EFI/refind; upgrading it. Found suspected Linux partition(s); installing ext4fs driver. Installing driver for ext4 (ext4_x64.efi) Copied rEFInd binary files Notice: Backed up existing icons directory as icons-backup. Existing refind.conf file found; copying sample file as refind.conf-sample to avoid overwriting your customizations.

Now Shut Down your Mac.

Disk Drive and Partitions

Bring up the Disk Utility and resize your macOS partition smaller to give more room to Ubuntu. If you have extra non-contiguous partitions which you cannot merge, you can at least format them as ExFat so Linux can see them later.

In detail, here are our disk partititions,

Seans-MBP:~ sean$ diskutil list /dev/disk0 (internal, physical): #: TYPE NAME SIZE IDENTIFIER 0: GUID_partition_scheme *320.1 GB disk0 1: EFI EFI 209.7 MB disk0s1 2: Linux Filesystem 130.0 GB disk0s2 3: Linux Swap 9.7 GB disk0s3 4: Apple_HFS Recovery HD 650.0 MB disk0s4 5: Microsoft Basic Data Untitled 100.5 GB disk0s5 6: Apple_Boot Recovery HD 650.0 MB disk0s6 7: Apple_CoreStorage Gauss 77.7 GB disk0s7 8: Apple_Boot Recovery HD 650.0 MB disk0s8 /dev/disk1 (internal, virtual): #: TYPE NAME SIZE IDENTIFIER 0: Apple_HFS Gauss +77.3 GB disk1 Logical Volume on disk0s7 D016C459-3197-4791-9145-96EF497E4E65 Unlocked Encrypted Seans-MBP:~ sean$ diskutil listFilesystems Formattable file systems These file system personalities can be used for erasing and partitioning. When specifying a personality as a parameter to a verb, case is not considered. Certain common aliases (also case-insensitive) are listed below as well. ------------------------------------------------------------------------------- PERSONALITY USER VISIBLE NAME ------------------------------------------------------------------------------- ExFAT ExFAT Free Space Free Space (or) free MS-DOS MS-DOS (FAT) MS-DOS FAT12 MS-DOS (FAT12) MS-DOS FAT16 MS-DOS (FAT16) MS-DOS FAT32 MS-DOS (FAT32) (or) fat32 HFS+ macOS Extended Case-sensitive HFS+ macOS Extended (Case-sensitive) (or) hfsx Case-sensitive Journaled HFS+ macOS Extended (Case-sensitive, Journaled) (or) jhfsx Journaled HFS+ macOS Extended (Journaled) (or) jhfs+
Create a Bootable Ubuntu USB Stick

Download Ubuntu Desktop, version Ubuntu 22.04.1 LTS (Jammy Jellyfish). You'll get a file in your Downloads folder called ubuntu-22.04.1-desktop-amd64.iso

Create a Bootable USB Stick for Mac. I'll go through a worked example below.

You'll need a 2GB USB thumb drive or larger. Insert it and bring up Disk Utility with the option of Show All Devices

Select the device, not the volume. Make sure it's NOT you hard drive or backup drive!

Now erase the disk specifying format = MS-DOS (FAT) and Scheme = GUID Partition Map

Next, install the open source utility Etcher, downloading the version for macOS.

Now run it, selecting the Ubuntu ISO file and the thumb drive the push Flash. Etcher will ask for your system password and give you an estimated time.

After completion, select Eject

Install Ubuntu

Connect an Ethernet cable to your Internet Service Provider and the other end to your Mac; use a USB to Ethernet dongle if you don't have a native Ethernet port on your Mac.

Plug the USB drive containing the Ubuntu Linux distribution into your Mac. Restart your Mac. If you installed rEFInd the boot manager will automatically appear. Select the EFI Boot icon from the list in the boot device menu.

If you have a problem seeing the boot manager, or if you already have done an Ubuntu installation do this: as soon as the Mac starts to boot up, hold down the Option key. Keep holding it down until you see the Mac's boot manager display a list of available devices you can start up from. Select the EFI Boot icon from the list in the boot device menu.

Now go through the Ubuntu installation process.

You'll see either This computer currently has no detected operating systems. Or if you had previously installed Ubuntu, This computer has Ubuntu 22.04.1 LTS (Jammy Jellyfish) on it.. Select something else since we want to fiddle with partitions.

Here is the list of partitions,

Now select the partition you want to use for Ubuntu (the 130GB) and hit - to delete it. You'll see it converted to free space.

Reformat the freespace using + as Ext4 journaling file system with mount point /.

Do the same for Linux swap space, giving yourself about 10GB,

Finally, click on the Format ? box, then click on Install Now

Your last chance, so double check what Ubuntu wants to do!

Now continue the installation. Ubuntu asks you where you are located. Next, enter user name and password. You will be the superuser.

Now let the installation complete, remove the thumb drive and reboot into Ubuntu automatically. Ubuntu asks if you want to update; say yes.

Just for grins, open Terminal and run a manual updating and upgrade all software, then remove unneeded software,

sudo apt-get update sudo apt-get upgrade sudo apt-get autoremove
Two Display Screens Show Up Instead of One

The Mac comes up with two displays shown. Toggle one display to avoid showing one blank display when screen sharing.

Ubuntu Freezing at Boot Time

My computer was freezing upon bootup. It's a problem with NVIDIA drivers, and you can fix Ubuntu freezing by turning them off at bootup. I'll repeat the instructions here with minor changes for my system. Upon bootup, hit the ESCAPE key once. You might have to experiment to get the timing right. You'll go into a boot menu,

Hit the E key to go into edit mode and add the option nomodeset after the the quiet splash in the linux line,

Then save and reboot. To make changes permanent, not just for this boot, edit the grub configuration file,

sudo gedit /etc/default/grub
sudo update-grub2
Wireless Connection

Connect to your local Wireless node by clicking on the top right menu bar settings.

Select Wireless settings, and type in your Wireless Key and connect.

If you cannot connect to Wireless, you may need to install the Wireless driver. I found it by looking at Broadcom Linux Wireless Drivers Install using the line below and reboot after you install.

sudo apt install bcmwl-kernel-source
Mounting an Additional FAT Partition

I had an unused partition, so I launched the Disks application and formatted it as Extended FAT to be visible to Ubuntu. You might have to toggle the Right Arrow icon to mount it; it will say mounted at /media/sean/Backup

Here then is the final partition map,
Reading USB Drives Formatted in Extended FAT

To read a USB drive formatted in Extended FAT format, install the drivers.

sudo apt-get install exfat-utils exfat-fuse

Now you can format a USB drive as Ex FAT, plug it into your computer, and read it.