M1 Mac Install Python 3.3.7

Installing legacy pythons is _hard_

I think that the trick to installing 3.3.7 is to have homebrew temporarily remove the openssl@1.1 library by entering brew uninstall openssl

Now, install pyenv with the target version, with all the compiler flags for zlib, bzip2 etc., and the arch detect patch.

brew uninstall --ignore-dependencies openssl@1.1

CPPFLAGS="-I$(brew --prefix openssl)/include -I$(brew --prefix bzip2)/include -I$(brew --prefix readline)/include -I$(xcrun --show-sdk-path)/usr/include" 

LDFLAGS="-L$(brew --prefix openssl)/lib -L$(brew --prefix readline)/lib -L$(brew --prefix zlib)/lib -L$(brew --prefix bzip2)/lib"

pyenv install --patch 3.3.7 < <(curl -sSL https://github.com/python/cpython/commit/8ea6353.patch)

This should force the installer to install the applicable (old) openssl == 1.0.2k and successfully complete.

Reinstall openssl@1.1 when complete.

Other things of note:

type in which python if it’s not the pyenv shim, add export PATH="$HOME/.pyenv/shims:$PATH" to your .zshrc

Top post here is also useful for a step by step forced Rosetta brew install that’s comprehensive https://stackoverflow.com/questions/65349982/issues-installing-python-3-x-via-pyenv

I’m still struggling to get a pyenv virtualenvwrapper pip install to appear from the local python.

More to come…

React Three Fiber Set Default Camera

To set the default camera in 2021+, use state.set exposed from useThree. Note that `setDefaultCamera` does not exist anymore, and every reference would use that.

“setDefaultCamera is not a function”

Instead, use the following:


const Camera = (props) => {
  const ref = useRef();
  const set = useThree((state) => state.set);
  useEffect(() => void set({ camera: ref.current }), []);
  useFrame(() => ref.current.updateMatrixWorld());
  return <perspectiveCamera ref={ref} {...props} />;
};

React three fiber docs (they are hard to find): https://docs.pmnd.rs/react-three-fiber/API/objects

Redux Toolkit – Solving Circular Action Dependencies

The singular struggle I have with Redux toolkit is that so much happens in the createSlice function that needing to deviating from it a little feels like a whole new pattern to adopt.

It’s crystal clear how to write the foundation, but the hallmarks of a great pattern are that you know exactly how to / where to place every type of exception you run into long term.

Say we have a simple createSlice function:

const doSomething = CaseReducer = (state, action) => {
    state.didSomething = true
}
const slice = createSlice({
  name: 'mySlice',
  reducers: { doSomething }
})

// some-other-file
slice.actions.doSomething()

If in the future, imagine this slice relies on an action from another slice (say a detail page needs to update the list page content) and we end up with a circular import. slice A imports slice B and slice B imports slice A.

How do we convert a slice action out of the helper and into its own file?

// my-shared-action.ts
// move the shared action to its own file. You will need to create its action and reducer which createSlice did automatically
const doSomething = createAction(
  "mySlice/doSomething",
  (myArg) => ({payload: myArg}) 
)
const doSomethingReducer: <CaseReducer> = (state, action) => {
  state.didSomething = true
}

// sliceA.ts
const slice = createSlice({
  name: 'mySlice',
  reducers: { },
  extraReducers: (builder) => {
    builder.addCase(doSomething.toString(), doSomethingReducer)  
  }
})

// sliceB.ts
const slice = createSlice({
  name: 'mySliceB',
  reducers: { },
  extraReducers: (builder) => {
    builder.addCase(doSomething.toString(), doSomethingReducer)  
  }
})

See we convert the createSlice action+reducer into one created from scratch in another file my-shared-action.ts using createAction and a plain reducer function.

We then import that action/reducer into two different slices, and register their reducers in their respective extraReducers properties.

Redux Toolkit TypeScript createSlice Reducers in Different File

If you want to define your reducers in a separate file from you createSlice function and type it correctly, you need to type your state manually which was previously handled by createSlice.

We will need to create 2 files: one for your slice state type (to prevent future circular import issues), and one for your new reducer functions.

// slice.type.ts 
export type MySliceState {
   foo: string
}

Now we’ll make a reducer object in another file

// reducers.ts
import { CaseReducer } from "@reduxjs/toolkit";
import { MySliceState} from "./slice.type.ts";

const doSomething : CaseReducer<MySliceState> = (state, 
action:PayloadAction<{foo: string}>) => {
       // state is now typed to MySliceState
  }
export myReducers = {
  doSomething,
}
// mySlice.ts
export const photosSlice = createSlice({
  name: "mySlice",
  initialState: {} as MySliceState,
  reducers: {
    ...myReducers,
  },

M1 Mac / Legacy Python 2.7 Project Setup

I ran into a bunch of roadblocks on this one around virtual environments.

  • Create Rosetta terminal
  • Install homebrew
  • brew install pyenv
  • pyenv install –patch 2.7.16 < <(curl -sSL https://github.com/python/cpython/commit/8ea6353.patch)
  • the above patch was critical to prevent a zlib issue
  • next, the virtual env was non straight forward to get working
  • pyenv local 2.7.16
  • brew install pyenv-virtualenvwrapper
  • export PYENV_VIRTUALENVWRAPPER_PREFER_PYVENV=”true”
  • pyenv virtualenvwrapper
  • mkvirtualenv/workon <venv>

MSI Z390I Intermittent Wifi Issues – Generally connects to internet but fails on games

I just put together a computer with the MSI Z390I board with integrated Wifi.

I fought an issue where I could connect to the internet, but not play Overwatch or connect to Blizzard servers. I got DNS resolution errors, and event logs for tons of wifi device resets.

The solution was that the drivers were too new for this board. Download the chipset drivers directly from the motherboard manufacturer’s website, and do not use Intel’s or Windows’s auto driver update.

 

Origin – DirectX Install Issues After Download Fixed

If you’re having trouble with Origin installs failing for every game, at the directX dependency installation step at the end, I found one solution.

Steam is rock solid on this one so… really highlights what’s sucking right now about having multiple stores. Imagine having to go to more stores than Amazon 🙂 There’s good and bad to it hah.

Anyhow, navigate to your Origin Games folder. Usually

C:/Program Files (x86)/Origin Games

Click into your game.

Click into the __install folder

Click into directx/redist

Delete all .cab files (maybe ~20 of them) such that there is only the directx installer and a few .dlls

Run the directx installer that’s in the folder

Reopen Origin

Done

iOS Safari iFrame and Z-Index Bug. Perceived Z index different from interaction z-index

I just ran into an issue with iOS that had me scratching my head. We have a Vimeo integration in an iframe that was playing on click on iOS safari (as evidenced by sound and network) but none of our JS handlers were being triggered.

The same site on Chrome and others would work fine and our JS handlers would be triggered, specifically an image on top of the iframe bound to click.

The problem turned out to be a Z-Index issue but somehow, the apparent/perceived/visible z-index was different from the interaction/touch/collision detection z-index. Increasing the Z-Index on the ​image gave it the priority it needed to be clickable.

 

Jekyll – Custom Sort Order Next and Previous Posts with Loop

To get the next and previous posts with a custom sort order with Jekyll, we need to do some fairly ridiculous logic with liquid.

Why is this worth posting? I’ve needed to do this multiple times, and this is the kind of thing you should be able to copy from the internet. Unfortunately each time I need it, “it doesn’t work” because of unintuitive liquid scope.

For example, you can’t increment the i variable in the below example inside of an if statement, but all’s well if you do it at the top level.

Anyway here’s the generic way to sort a Jekyll collection by an arbitrary sort key:

{% assign posts = site.products | sort: 'position' %}
{% assign i = 0 %}

{% for post in posts %}

  {% assign nextIndex = i | plus: 1 %}
  {% assign prevIndex = i | minus: 1 %}

  {% if post.title == page.title %}
    
  	we've looped through posts in our custom sort order 
  	until we've found our matching post.
    
    {% if forloop.first %}

      if it's the first loop, then the previous post is the last item
      {% assign prev = posts.last %}

    {% else %}

      otherwise, the previous post is the previous index
      {% assign prev = posts[prevIndex] %}

    {% endif %}


    {% if forloop.last %}

      if it's the last loop, then the next post is the first item
      {% assign next = posts.first %}

    {% else %}

      otherwise, the next post is the next index
      {% assign next = posts[nextIndex] %}
      
    {% endif %}

  {% endif %}

  {% assign i = i | plus: 1 %}
{% endfor %}