See the real details of a git commit

The command to see the details of a git commit, specifically the tree attached to it, is:

git cat-file -p HEAD

It produces an output like this:

jason@rise22:~/code/appcove/HKSickler$ git cat-file -p HEAD
tree f388dffd7ac29813d4a61a1cfd9f4a03518c3c56
parent 2752fafb51cb58c288adcd5d0a6f262943416683
parent cd6ce6f905ef61d019fbbd16e157ef0389f809ef
author Jason Garber <jgarber@appcove.com> 1669396739 -0500
committer Jason Garber <jgarber@appcove.com> 1669396739 -0500

Merge: merge this and that ....

Ubuntu 22.04 having trouble with desktop icons?

In a previous post I showed how to fix Ubuntu 20.04 icons. Now with 22.04 it is a bit different. What would normally work does not work now because Firefox is running as a snap package and cannot manage Gnome extensions.

It’s easier this time. Install the Gnome Shell Extension Manager (https://github.com/mjakeman/extension-manager/tree/master/src) like this:

$ sudo apt info gnome-shell-extension-manager

Then run it:
$ extension-manager

Here is an example of me installing and running it…

Go to the Browse tab and search for “neo “

Install Desktop Icons: Neo

Go back to the Installed tab and enable it, and disable the other Desktop Icons NG (DING) extension

There you go!

Creo 7: All from a sketch

One of the harder things in designing machines is figuring out how all of the parts interface with each other precisely. In Creo 7 Parametric, the ability exists to draw a series of master sketches which describe how parts interface, then extrude new bodies from these sketches, then create new parts from the bodies, and finally assemble them.

In this case we wanted to make sure that the follower, despite it’s curved shape, moved perpendicular to the surface of the wheel. We created a series of 4 sketches using many construction lines (which don’t show up after you exit sketching mode). These sketches described the key interface and clearance parts of the mechanism, including the maximum and minimum location of the follower as it rides over the highs and lows of the cam wheel. Using this geometry, we could accurately place the tension spring to put a calculated amount of force between the two parts, while ensuring that there was no part interference.

Additional sketches were then created referencing this base geometry to put the finer details on the actual parts to be extruded. They were then extruded, carefully being sure to mark them each as new bodies. Notice even the pin itself was sketched here because all of the pin holes and the pin itself might as well reference the same size circle.

Each body was then saved to it’s own part:

And finishing touches were placed on each part in it’s own file. It’s important not to clutter up the base part too much, but rather keep it focused on overall shapes to the degree needed to ensure everything fits.

Finally all parts were assembled into an assembly, and further revisions were made to the base sketches to improve overall look, size, and function.

Creo 7 Parametric Assemblies

Creo 7 Parametric Assemblies

A point of confusion when learning Creo 7 (coming from Fusion 360 and previously SolidWorks) was how to mate parts in an assembly. Like many things, once you know it’s pretty simple!

It is at the point you are inserting the part into the assembly that you are able to specify constraints/mates.

You can reopen this area of the application by clicking on a part and then then clicking Edit Definition.

Equations in PTC Creo 7

Equations in PTC Creo 7

Today I learned that Creo Parametric has first class support for equations which can be turned into sketch items, and the incorporated into a model. In this example I created a sine wave.

y = sin(x*2) * 100

And told Creo to extend it from x=0 to x=900. Here is a picture of editing the equation.

Once I had that curve defined, I created a sketch on the same plane, and then used the “Project” tool to project the sinewave into the current sketch. After adding sides and a bottom, I had a closed shape.

From there it was a simple matter to extrude, offset, cut, and add some colors.

Auto Resize IFRAME Cross Origin

Browser security policies prevent frames from interacting with each other if they are not from the same origin (like domain but even more specific).

However, frames can pass messages to each other.   Here is how you can implement cross-origin iframe auto-resizing based on window.postMessage.

Lets assume we have a parent page that looks like this:

<html>
  <head>
    <title>Parent Page</title>
  </head>
  <body>
     ...
     [iframe id="frame1" src="https://otherdomain.com/frame1.html"]
  </body>
</html>

(assume [] is <> above, sorry about over protective content escaping in wordpress.com)

To enable auto-resizing on this page, add some script to the end of the <head></head> section (or just before </body> if that is where you put them).

This listens for a “message” event and will check to see if it has an action of “resize”.  If so it will update the specified id’s height.

<script>
  window.addEventListener("message",function(e){
    if(e.data.action=='resize') {
      document.getElementById(e.data.id).style.height = e.data.height+'px';
    }
  },
  false
  );
</script>

On the embedded frame source, you need an onload event to send a message:

window.onload = function() { 
  window.parent.postMessage({action:'resize',id:'frame1',height:document.body.scrollHeight+20},'*');
};

Note that we need to pass “frame1” which is the ID of the frame on the parent page.

Then the frames should auto-size to their content.

Reset MySQL or MariaDB root password

If you need a super easy way to reset your MySQL or MariaDB root password because you locked yourself out, this is how it can be done.

  • Login as root@yourhost
  • Shutdown any remote access as your server will be without password for a few moments.
  • Edit /etc/my.cnf, and under the [server] section, add
[server]
skip-grant-tables
  • Restart MySQL
  • Login and update the password with a query like this:
# mysql
MariaDB> use mysql;
MariaDB> update user set 
Password=PASSWORD("yourpass"),
authentication_string=PASSWORD("yourpass") 
where User='root';
  • Remove the “skip-grant-tables” line from /etc/my.cnf
  • Restart mysql

You are back in action!  Don’t forget to re-enable remote access.

 

Installing Windows Subsystem for Linux (WSL) on Windows 10

Microsoft has been doing a lot to promote linux  interoperability on windows.  I see this as a great step in the right direction, after decades of a closed and exclusive culture that has been a pain for cross-os users like myself.

Here is a quick and dirty rundown of how (March 2019) to install Ubuntu on Windows 10:

See here for the full rundown: https://docs.microsoft.com/en-us/windows/wsl/install-win10

Install the Windows Subsystem for Linux

Before installing any Linux distros for WSL, you must ensure that the “Windows Subsystem for Linux” optional feature is enabled:

  1. Open PowerShell as Administrator (search for Powershell, right click, run as administrator), and run this command:
    Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
    
  2. Restart your computer when prompted.

Install your Linux Distribution of Choice

Go to the Microsoft Store and search for Ubuntu.  Install it.

Once you are in Ubuntu, there are a few things to do that will make everything nicer…

Update Ubuntu and setup ssh server
sudo apt-get update
sudo apt-get dist-upgrade
sudo apt-get install openssh-server
sudo service ssh start

Fix character encoding issue (until this is fixed upstream)
sudo gunzip –keep /usr/share/i18n/charmaps/UTF-8.gz
sudo dpkg-reconfigure –frontend=noninteractive locales

Setup SSH under your user
mkdir .ssh
chmod 700 .ssh
touch .ssh/authorized_keys
chmod 600 .ssh/authorized_keys
(put your public key in there)
Setup PuTTY
You can then configure PuTTY to connect to 127.0.0.1 port 22 with your username and key (ideally from Pageant)
You can access your c drive under /mnt/c/
You can access your desktop using /mnt/c/Users/YOU/Desktop
This enables you to write convenient scripts in ubuntu that affect windows files on your desktop for example.

Python Mutable vs Immutable

Here is a basic introduction to immutable and immutable types in python.

In python there are two types of data… mutable and immutable. Numbers, strings, boolean, tuples, and other simple types are immutable. Dicts, lists, sets, objects, classes, and other complex types are mutable.

When you say:

a = [1,2,3]
b = a

You’ve created a single mutable list in memory, assigned a to point to it, and then assigned b to point to it. It’s the same thing in memory.

Therefore when you mutate it (modify it):

b[0] = 3

It is a modification (mutation) of the index [0] of the value which b points to at that same memory location.

However, when you replace it:

b = [0,0,0]

It is creating a new mutable list in memory and assigning b to point at it.


Check out the id() function. It will tell you the “address” of any variable. You can see which names are pointing to the same memory location with id(varname).


Bonus: Every value in python is passed by reference… meaning that when you assign it to a variable it simply causes that variable to point to that value where it was in memory. Having immutable types allows python to “reuse” the same memory location for common immutable types.

Consider some common values when the interpreter starts up.  You can see here there are a lot of variables pointing at the memory location held by abc.  cpython, at least, is smart enough to realize that the value `abc` is already stored in memory and because it is immutable, just returns that same memory address.

>>> import sys
>>> sys.getrefcount('abc')
68
>>> sys.getrefcount(100)
110
>>> sys.getrefcount(2)
6471

However, a value that is definitely not present would return 2. This has to do with the fact that a couple of references to that value were in-use during the call to sys.getrefcount

>>> sys.getrefcount('nope not me.  I am definitely not here already.')
2

Notice that an empty tuple has a lot of references:

>>> sys.getrefcount(tuple())
34571

But an empty list has no extra references:

>>> sys.getrefcount(list())
1

Why is this? Because tuple is immutable so it is fine to share that value across any number of variables. However, lists are mutable so they MUST NOT be shared across arbitrary variables or changes to one would affect the others.

Incidentally, this is also why you must NEVER use mutable types as default argument values to functions. Consider this innocent little function:

>>> def foo(value=[]):
...     value.append(1)
...     print(value)
...
...

When you call it you might expect to get [1] printed…

>>> foo()
[1]

However, when you call it again, you prob. won’t expect to get [1,1] out… ???

>>> foo()
[1, 1]

And on and on…

>>> foo()
[1, 1, 1]

>>> foo()
[1, 1, 1, 1]

WHY IS THIS? Because default arguments to functions are evaluated once during function definition, and not at function run time. That way if you use a mutable value as a default argument value, then you will be stuck with that one value, mutating in unexpected ways as the function is called multiple times.

The proper way to do it is this:

>>> def foo(value=None):
...     if value is None:
...         value = []
...     value.append(1)
...     print(value)
...
...
>>>
>>> foo()
[1]
>>> foo()
[1]
>>> foo()
[1]