Elements of Software Construction [1] (MIT OCW 6.005 2008) has an excellent practical introduction to programming with the State Machine paradigm.
It uses Java but is applicable to any language because it's a design centric approach. In particular, lectures [2] [3] [4] [5].
It relies on a very lightweight notation and presents a choice of 4 design patterns (not just GoF State) to synthesise the code directly from the design [3].
[4] shows how to apply invariant reasoning to State Machine design, which is an extremely powerful reasoning tool.
[5] is very interesting because it explains how to deal with structured traces, which are modelled as streams using a regular grammar. This turns out to be a very simple but powerful design approach that is applicable to many situations, and very straightforward to implement using JSP (nothing to do with Java, stands for Jackson Structured Programming). Because this is basically a parser (at a very abstract level), the course then follows naturally to the FP paradigm.
It also includes a couple of very cool hands-on exercises:
Multipart file transfer [6] [7]
Midi piano player [8]
In fact, the whole course is outstanding.
[1] https://ocw.mit.edu/courses/electrical-engineering-and-compu...
[2] https://ocw.mit.edu/courses/electrical-engineering-and-compu...
[3] https://ocw.mit.edu/courses/electrical-engineering-and-compu...
[4] https://ocw.mit.edu/courses/electrical-engineering-and-compu...
[5] https://ocw.mit.edu/courses/electrical-engineering-and-compu...
[6] https://ocw.mit.edu/courses/electrical-engineering-and-compu...
[7] https://ocw.mit.edu/courses/electrical-engineering-and-compu...
[8] https://ocw.mit.edu/courses/electrical-engineering-and-compu...