Algorithmic thinking: A problem-based introduction

(Daniel Zingaro) This text draws inspiration from coding challenge problems to teach algorithmic thinking: classifying problems, selecting data structures, and implementing appropriate algorithms.

Learn to code by solving problems: A python-based introduction

(Daniel Zingaro) An introduction to programming that draws inspiration from coding challenges and provides practice not only with Python but also introduces fundamental data structures.

Practical Programming: An Introduction to Computer Science Using Python 3

(Paul Gries, Jennifer Campbell, and Jason Montojo) An introduction to Python programming and problem solving that pairs with a Coursera MOOC.