Part 1
For not_in_preamble, I'd use a for-else instead of your found variable, and not re-use the same set (I don't think it's worth it):
def not_in_preamble(nums, preamble):
for i in range(preamble, len(nums)):
current = nums[i]
diff = set()
for j in range(i - preamble, i):
if nums[j] in diff:
break
diff.add(current - nums[j])
else:
return current
Since your "Any other feedback or alternative solutions are welcome" also allows less efficient solutions, here's how I actually solved it myself :-)
from itertools import combinations
def not_in_preamble(nums, preamble):
for i in range(preamble, len(nums)):
if nums[i] not in map(sum, combinations(nums[i-preamble : i], 2)):
return nums[i]
Preamble size 25 and nums size 1000 are easily small enough for that to run quickly.
Part 2
Your sub_array_with_sum is great, although it does rely on the input being non-negative numbers, which isn't guaranteed in the problem statement (but is the case for the fixed input file).
I'd just go with PEP 8 and change nums[i: j + 1] to nums[i : j + 1] or nums[i : j+1]. And perhaps I'd go with while True:, relying on the existence of an answer.
Your algorithm almost only takes O(1) space. The only reason it takes more is copying out the sub-array (or rather sub-list, as this is Python and the problem never says "array", so there's really no need to call it array). Could be done in O(1) space to make the algorithm not just time-optimal (O(n)) but also space-optimal. Though that would require more code, not worth it (unless you have an interviewer who insists).
Input
I'd change [int(l) for l in f.read().splitlines()] to list(map(int, f)), or at least [int(line) for line in f].
Output
I'd change
print(f'PT 1 result: {pt1_result}') to
print('PT 1 result:', pt1_result). Bit shorter, and it works in older versions of Python. And at least in IDLE, the f-string is styled only as string, the whole thing green, including the variable. I don't like that.