Python Notes

The following are a few notes on the syntax, commands, etc. for python programming Assumes python version 3.x, which differs substantially from the 2.x versions. Python is not backwards-compatible, so 2.x codes don't necessarily work in 3.x.


python prog.py                   # Run python, where prog.py is a python program
python prog.py arg1 arg2         # Run python program with arguments
                                 #  inside the code you must 'import sys', and then
                                 #    str(sys.argv[0]) is 'prog.py'
                                 #    str(sys.argv[1]) is the first argument, etc.


---------------Numbers, Statistics, Vectors--------------------

# + - / * do what you'd think. ** is a power, abs is absolute value
# pow(2,7) is the same as 2**7, max and min do what you'd think
# round(2.71828,4) gives 2.7183
# 10%3         # 10mod(3) = 1
# str(10%3)    # '1' returned as a string
# float('3.44') # converts a string to a floating point number
                # NOTE: ALL PYTHON inputs from the user are interpreted as strings

# Running it from the command line; most useful as a calculator
python                           # Start python (or python3 for version 3.3)
>>> import numpy as np           # import package numpy
>>> print(np.sin(np.pi/4.))      # prints 0.7071067...; need np.sin as sin is not defined
>>> a=500.3
>>> b=3
>>> a/b                          # prints out 166.7666
>>> _/5.                         # prints 33.3533   _ is the result from the last command
>>> Ctl-D                        # quit

# setting x=[1.3,2.4,8] is a list, these behave like strings
# setting x=(1.3,2.4,8) is a tuple, these are like lists that can't be changed
# np.array([1.3,2.4,8]) is what you want for a vector (1D array)
np.zeros(10, dtype=np.int)  # initialize an integer array of 10 elements to zero
np.ceil([2.87])   # rounds up to 3
np.array([2.87,4.8], dtype=int) # rounds to [2,4]  !!Use this, and not np.int!!
np.floor([2.87,4.8]) # rounds to [2.,4.] but these are reals
np.arange(0,5,0.1) # makes [0, 0.1, 0.2 ... 4.9, 5.0] vector
np.random.rand(5) # five random numbers between 0 and 1
np.random.randn(5) # five random numbers from std normal distribution
np.random.randint(0,99,5) # five random integers between 0 and 99
np.mean(x)       # mean of x
np.var(x)        # variance of x   DONT FORGET THE 'np.' 
np.std(x)        # stddev of x
np.log(x)        # ln(x)
np.log10(x)      # log10(x)
np.exp(x)        # exp(x)
np.arctan(x)     # atan(x)


---------------Plots--------------------
import matplotlib.pyplot as plt  #MATLAB-like plots
from astropy.io import ascii
data=ascii.read('junk.txt', header_start=0, data_start=1, delimiter=" ")
  #junk.txt has a line of header: name, B-V, and mag, and then data
plt.figure(1)  #in case you want multiple figures or subplots
plt.figure(figuresize=(15,15))  #make the plot bigger
plt.subplot(325)  #3 rows, 2 columns of plots; access plot number 5 of these
plt.plot(data['B-V'],data['mag'], 'bx')  #plot blue x's. r-- is red dashed lines, etc.
plt.plot(x,y,lw=2.2)  #Thicker line width
plt.axis([-0.2,0.8,11,5])  #limits on x- and y-axes
plt.ylim(-2,2) #another way to set y limits
plt.grid(True)  #add a grid
plt.text(60, .025, r'$\mu=100,\ \sigma=15$')
plt.yscale('log')  # log_10 scale on y-axis
plt.ylabel('Mag', fontsize=14)  # y-label
plt.xlabel('B-V', fontsize=14)  # x-label
plt.title(r'$\sigma_{15}$ Some title')  # A plot title. The r means a raw string (for latex \)
plt.hist(x,30,facecolor='b',range=[0.9,1.1]) #histogram of x, 30 bins in [0.9,1.1]
plt.show()         # Displays the plot

# colors: (r)ed, (g)reen, (b)lue, (w)hite, blac(k), (c)yan, (m)agenta, (y)ellow,
#  hundreds of others like 'darkblue', 'forestgreen', 'brown', etc.
# linestyles:  : dotted; - solid; -- dashed; -. dot-dashed;  possible to make your own



---------------Strings--------------------

# Assigning, concantating strings
c="hello"
ss=c+" "+c      # ss = "hello hello" 

# uppercase and lowercase
ss= "HEllo"
ss.upper()     #would be HELLO
ss.lower()     #would be hello
ss.isupper()   #returns False because HEllo is not all uppercase

# string length
ss="lasjhf"
len(ss)       # equals 6

# substrings and positions in a string, replacing strings
ss=Hi there"
ss[1:4]      # equals 'i th' because the index starts at 0
ss[len(ss)-3:len(ss)-1]  # 'ere' the last three characters
ss[-2]       # second to last character, 'r'
ss[-2:]      # second to last character to the end of the string, 're'
ss[::-1]     #reverses the string, 'ereht iH'
ss.index("h")    # equals 4 in this case
ss.index("her") # also equals 4, the location of the beginning of 'her' 
ss.replace("her","eak")  # gives 'Hi teake'

#         Formatted print statements
print("{0:5.3f} {1:3d}".format(var,num))  #the 0: is the first argument (var),
                                          #    1: is the second argument (num)
print('Input filename: ',end="")          # stops the carriage return
print('12'.zfill(5))             # for leading zeros, prints 00012


-----I/O into a program, open and write to output files -------

name=input("Input filename: ")                    # read name from terminal
oname="out_"+name               # make output filename
fin= open(name,'r')             # open input filename to read  'a' would be to append
fout= open(oname,'w')           # open output filename to write (overwrite) an entirely new file
for line in fin:                # loop until run out of lines
 line=line.strip()            # get rid of invisible characters like \n
 columns=line.split()         # split the fields of the line
 var1=float(columns[0])      # columns[0] and columns[1] are strings
 var2=float(columns[1])
 fout.write('{0:9.4f} {1:9.4f}\n'.format(var1-var2,var1*var2))
fin.close()
fout.close()

tfile=open('times', "r")
line=tfile.readline()    # read in first line
while line:              # read in subsequent nonzero lines
 print(line)
 line=tfile.readline()
tfile.close()

name.readable()   # True if file can be read
name.readline()   # reads in a line
name.readlines()  # reads file into a list
name.write("\n adding this line to file") # for appending to existing files

a,b = float(input("Type in two values: ").split())  # input 2 real values

from astropy.io import ascii
data=ascii.read('gc.dat', header_start=0, data_start=1, delimiter=" ")
data.more()                      #To interactively page through the table
data.info                        #shows what columns are what and their type
data.colnames                    #list column names
data.rename_column('dia','D')    #rename a column
data['newcol'] = [2,4,5,2,3,5]   #add a column named 'newcol'
data.remove_column('newcol')     #remove a column 
data['dia'].format = '7.3f'      #changes format of column 'dia'
data['dia','B-V']                #a table with only these two columns
data.add_row(3344,344.4,-13.4,12.3,8.9]  #add a row
data1=data[np.where((data['long']<20) & (data['dia']>10))] #extract subset


------- if, for, while statements; looping ----------
flag1=True
flag2 = False
if flag1 and flag2:    # you can also use 'or'.  DONT FORGET the :
 print("ok")
elif flag1 and not(flag2): # use of 'not' function
 print("maybe ok")
else:
 print("not ok")

if num1 >= num2 and num2 != num3:  # For numbers
 print(num1,num2)
print("done with loop")

for iv in list(range(8, 12)) :
 print(iv-2.3)

for iv in range(np.size(vs)) :
 print(iv-2)

i=0
while (i< len(data['ra'])): 
 print(i)
 i+=1
print("done with loop")

while True:
 try:
  a=int(input("Input an integer: "))
  break                              # break out of what would be an infinite while loop
 except ValueError:                  # If they didnt input an integer
  a=0
  print("You need an integer here")
print(a)


-----Lists-------
list=["bobby",23,"billy",55.3]   
list[2]         # this is "billy"
list[-1]        # this is 55.3, go from the end
list[2:]        # starts at element 2 and goes to the end:  ["billy",55.3]
list1=["a","b"]
list2=[1,2]
list1.extend(list2) # glues lists together: ["a","b",1,2] and overwrites list1
list2.append(5)     # list2 is now [1,2,5]
list2.index(5)      # returns 2, the index location of element '5'
list2.count(5)      # number of times '5' occurs in the list
list2.insert(1,12)  # list2 is now [1,12,2,5]
list2.remove(12)    # removes first occurrence of 12
list2.pop()         # remove last element from list
list.sort()         # sorts the list
list.reverse()      # reverse sorts the list
list2.clear()       # clears the list
list3=list1.copy()  # copies a list
list4=[[0,3,5],[9,4,2],[0]]  # list4[1][0] = 9 in this case

array = (2,4)       # this is a 'tuple' and can never be changed
                    # so you can't change the 4 to a 5, for example (seems stupid)


---------------Dictionaries--------------------
dateno = {         # this defines the dictionary with a key/value
"jan": "0",        # e.g. mar/59
"feb": "31",
"mar": "59",
"apr": "90",
"may": "120",
"jun": "151",
"jul": "181",
"aug": "212",
"sep": "243",
"oct": "273",
"nov": "304",
"dec": "334",
}
while (True):
 a,b = input("Date (e.g. Feb 22): ").split()  #input multiple values on one line
 aa = dateno.get(a.lower()[0:3],"Bad")        # Apr -> 90, etc. Apq -> "Bad"
 if aa == "Bad":
   print("screwup")
 else:
   print(int(aa)+int(b))



---------------Error Handling--------------------

while True:
 try:
  a=int(input("Input an integer: "))
  break                              # break out of the infinite while loop
 except ValueError:                  # If they didnt input an integer
  print("You need an integer here")
print(a)


---------------Classes --------------------
class exam:              # Define a new class of objects
   def __init__(self,question,answer):   # exam objects consist of a question and an answer
      self.quest = question   # e1.quest will refer to question part of the exam element e1
      self.ans = answer      # e1.ans will refer to answer part of the exam element e1

                # make a list of questions
questions = [
"Is the sky blue?\n(a) yes\n(b) no\n\n",
"Does Trump have yellow hair?\n(a) yes\n(b) no\n\n",
"What color are the Rams jerseys?\n(a) purple\n(b) pink\n(c)yellow and blue\n\n",
]

key = [                  #the list 'key' contains exam objects
exam(questions[0],"a"),   
exam(questions[1],"a"),
exam(questions[2],"c")
]

score=0
for i in key:            #each i is an exam object
 answer=input(i.quest)   #asks for user input with the prompt i.quest = questions[i]
 if(answer == i.ans):
   score += 1
print("You got " + str(score) + "/" + str(len(key)) + " Correct")


---------------Subroutines (functions)--------------------
def yrs_since_HS(age):
  return(age-18)
print(yrs_since_HS(55)) # gives 37.  Input was age, returned value is age-18


---------------Modules and Importing--------------------
import numpy as np
np.pi                 # 3.14159265...
pip install module
pip uninstall module


---------------Interact with the operating system--------------------

# To execute a command from the OS and print the results to STDOUT, precede with a '!'
!pwd

# To call a command from the OS:
from subprocess import call
call(["/bin/ls","-lt"])  # if successful it simply exits with code '0'

# To call a command from the OS that uses pipes:
import subprocess
p1=subprocess.Popen(["/bin/ls"],stdout=subprocess.PIPE)   #first command
p2=subprocess.Popen(["/usr/bin/awk","END{print NR}"],stdin=p1.stdout,stdout=subprocess.PIPE) #pipe to second command
p1.stdout.close() #apparently so the order of finishing doesn't matter
output=p2.communicate()[0] #set the result from the pipe (a byte string) to 'output'
print(output.decode('ascii')) #print out this byte string as ascii

# To write python commands to a file, and then execute that file in a double loop
# Note if you forget the () in g.close the python code will skip one command
#  and you get a real mess, with only 5 output files instead of 6 and mixed up contents
#  That's because the file remains open, and only closes when it reloops
from subprocess import call
import numpy as np
vs=(20,30)
denz=(10,20,30)
for iv in range(np.size(vs)) :
 for id in range(np.size(denz)) :
  fout=open("jj",'w')
  fout.write('{0:10.2f}  {1:4.2f} VS DEN\n'.format(vs[iv],denz[id]))
  fout.close()

  g=open("doit",'w')
  g.write('cp -f jj test_{0:2d}_{1:4.2f}.txt\n'.format(int(vs[iv]),denz[id]))
  g.close()   # Don't forget the ()!!!
  call(["/bin/tcsh","doit"])

---------------Jupyter Notebook--------------------

# To start up Jupyter:
jupyter notebook  # will create a .ipynb file (the notebook) in the current directory
                  # uses  ~/.jupyter/nbconfig/notebook.json for shortcuts
                  # These are vi-like
                  # Jupyter has an insert mode and an escape mode like vi
                  # Don't be afraid to restart the kernel if it gets confused

jupyter nbconvert --to python nbname # Converts nbname.ipynb to nbname.py, a python code file
                                     # you can run via 'python nbname.py'
       # Note, jupyter notebooks are really json files, meaning they
       # are text files that can be edited