IO & Streams

file handling

$ \qquad\qquad \begin{array}{|l|c|c|c|c|c|c|} \hline & \ r\ & r+ & \ w\ & w+ & \ a\ & a+ \\ \hline \mathrm{read} & * & * & & * & & * \\ \hline \mathrm{write} & & * & * & * & * & * \\ \hline \mathrm{create} & & & * & * & * & * \\ \hline \mathrm{truncate} & & & * & * & & \\ \hline \mathrm{position\ at\ start} & * & * & * & * & & \\ \hline \mathrm{position\ at\ end} & & & & & * & * \\ \hline \end{array} $
Copy Copy to clipboad
Downlaod Download
#!/usr/bin/env python3

import os      # miscellaneous operating system interfaces

myText = "However fast you may be able to think,\nit is not fast enough."
f_out = open("output.txt", "w")           # write stream (to file)
f_out.write(myText)                       # writing to stream
f_out.close()                             # closing stream

os.system("cp output.txt input.txt")      # copy files

f_in = open("input.txt")                  # reading is the default
print("# f_in :\n", f_in.read(), sep="")  # file to string --> print
f_in.close()

print()
with open("input.txt", "r") as g_in:  # open with 'with'
  lineCount = 0
  for line in g_in:                   # reading line by line
    lineCount += 1
    print(f'reading/printing line {lineCount:3d} ',line, end="")
  print()

# cleaning up
if 1==2:
  os.remove("input.txt")
  os.remove("output.txt")

compressed file handling

Copy Copy to clipboad
Downlaod Download
#!/usr/bin/env python3

# line continuations with ( ... )
myText = ( "However fast you may be able to think,\n"
         + "it is not fast enough.\n" 
         + "Don't worry, others have the same problem;)" )

# direct use of file streams
open("thinking.txt", "w").write(myText)
data = open("thinking.txt", "r").read()

# line continuations with  \
for token in data.replace('\n',' ').replace('.',' ').\
                  replace(', ',' ').replace('  ',' ').split(" "):
  print(token)

function generators

Copy Copy to clipboad
Downlaod Download
#!/usr/bin/env python3

# best pratice doc string, as suggested by an LLM
def tokenizer(inString):
    """
    Yields successive tokens from a string separated by single spaces.

    This is a generator function that scans the input string from left
    to right and yields each substring between space characters. An
    extra space is appended internally so that the final token is yielded
    without requiring special handling after the loop.

    Notes:
        - Only the space character (' ') is treated as a separator.
        - Consecutive spaces produce empty-string tokens.
        - Leading or trailing spaces also produce empty-string tokens.

    Args:
        inString (str):
            The string to tokenize.

    Yields:
        str:
            The next token found in the input string.

    Example:
        >>> list(tokenizer("one two three"))
        ['one', 'two', 'three']

        >>> list(tokenizer("one  two"))
        ['one', '', 'two']
    """
  sepChar = " "
  lastPos = 0
  inString = inString + sepChar     # seperation token
  for ii in range(len(inString)):
    if inString[ii] == sepChar:
      yield inString[lastPos:ii]
#      print(ii, inString, inString[lastPos:ii])
      lastPos = ii + 1

def fibonacci(maxN):
   x, y = 0, 1
   for _ in range(maxN):            # no variable needed
     x, y = y, x+y
     yield x


myText = "Warum bin ich hier?"
myList = [x for x in myText]
print("\nmyText\n",myText)
print("\nmyList\n",myList)
print()
myGenerator = tokenizer(myText)
print("type(myText)      : ", type(myText))
print("type(myList)      : ", type(myList))
print("type(myGenerator) : ", type(myGenerator))

print()
print("*** myList ***")
for cc in myList:
  print(cc, end='')                 # no endline
print()
print()

print("*** myGenerator ***")
for cc in myGenerator:
  print(cc, "",  end='')
print()

print("*********")
print("fibonacci")
print("*********")

[print(ff) for ff in fibonacci(5)]  # generator comprehension
print()
print(sum(fibonacci(5)))            # shortcut

exceptions

Copy Copy to clipboad
Downlaod Download
#!/usr/bin/env python3
import math

def myLog(x):
  if not type(x) is float:
     raise TypeError("only myLog(x) if x is float")
  if x <= 0:
     raise Exception("only myLog(x) when x>0")
  return math.log(x)


print("************************")
print("basic exception handling")
print("************************")
try:
  print(x)
except NameError:
  print("undefined variable")
except:
  print("something went wrong")

print()
print("*******************************************")
print("catching user-defined exceptions / messages")
print("*******************************************")
try:
  myLog(0.0)
except TypeError as message:
  print("a type error occured: " + str(message))
except Exception as message:
  print("something went wrong: "   + str(message)) 
else:
  print("nothing went wrong")
finally:                                  # always executed
  print("'try except finally' finished")

print()
print("***********************")
print("input/output exceptions")
print("***********************")
fileName = "demo.txt"
try:
  f = open(fileName)                      # default, reading only
  try:
    f.write("Lorum Ipsum")
  except:
    print("failed to write to " + fileName)
  finally:
    f.close()
except:
  print("failed opening of " + fileName)

running with arguments

Copy Copy to clipboad
Downlaod Download
#!/usr/bin/env python3
import sys     # standard system module
import os      # miscellaneous operating system interfaces

fN = 'counting.txt'

if not os.path.isfile(fN):            # 'is file'
  with open(fN, 'w') as f:            # short for try-catch block 
    f.write("1")

with open(fN, 'r+') as g:             # read and write
  if (var:=int(g.read())) >= 100000:  # exit when too large
    exit()
  print("content of ", fN, " : ", var)
  g.write("0")                        # appending, because did read first

print(sys.argv) 
os.system(sys.argv[0])                # running self

serialization

Copy Copy to clipboad
Downlaod Download
#!/usr/bin/env python3

import pickle, json

data = {'name': 'Alice', 'age': 30, 'city': 'New York'}

# binary serialization, dumping to file
with open('data.pkl', 'wb') as file:
    pickle.dump(data, file)

# human-readable json file
data['city'] = 'Wonderland'
with open('data.json', 'w') as file:
    json.dump(data, file, indent=4)

# deserialization, loading from file
with open('data.pkl', 'rb') as file:
    data_pickle = pickle.load(file)

# direct reading
with open("data.json") as f:
    data_json = json.load(f)

print(data_pickle)
print(data_json)