Python 101 - MacAdmins Conference | Join us 6/3
Transcript of Python 101 - MacAdmins Conference | Join us 6/3
![Page 1: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/1.jpg)
Python 101
PSU MacAdmins 2019@chilcote
![Page 2: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/2.jpg)
Who am I?@chilcote
CPE @ Facebook
18yrs as a Mac Admin
Writing python for ~6 years
No clue what I'm doing
![Page 3: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/3.jpg)
Interactive session
>>> import platform>>> platform.node()'chilcote-mac'
Break out your Mac
Try simple examples
No making fun of me in slack
![Page 4: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/4.jpg)
Raise your hand if you have written python before.
![Page 5: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/5.jpg)
Raise your hand if you have written bash before.
![Page 6: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/6.jpg)
Raise your hand.
![Page 7: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/7.jpg)
Raise your hand if you have written bash before.
![Page 8: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/8.jpg)
Shell% tail ~/.bash_historycd ~/Desktopsudo vfuse --list-templatessudo vfuse -t Mojaveopen Mojave.vmwarevm/sudo softwareupdate -l
![Page 9: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/9.jpg)
Don't do this% bash ~/.bash_history
![Page 10: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/10.jpg)
Python% python >>> import antigravity
![Page 11: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/11.jpg)
https://xkcd.com/353/
![Page 12: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/12.jpg)
Python% python >>> import antigravity>>> quit()
![Page 13: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/13.jpg)
Raise your hand if you have written python before.
![Page 14: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/14.jpg)
Why python?Shell works just fine!
● More than running commands● Manipulating text● Structured data● Cross-platform
![Page 15: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/15.jpg)
Who did this?Guido van Rossum Late 1980sBenevolent Dictator for Life(or at least until 2018)
@gvanrossum
![Page 16: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/16.jpg)
Why "python?""I chose Python as a working title for the project, being in a slightly irreverent mood (and a big fan of Monty Python's Flying Circus)."https://www.python.org/doc/essays/foreword/
https://en.wikipedia.org/wiki/Monty_Python
![Page 17: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/17.jpg)
Releases1994: Python 1.02000: Python 2.02008: Python 3.0
![Page 18: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/18.jpg)
CharacteristicsHigh-levelInterpretedGeneral-PurposeExtensible
![Page 19: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/19.jpg)
"There should be one— and preferably only one—
obvious way to do it."
![Page 20: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/20.jpg)
>>> import this
![Page 21: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/21.jpg)
>>> import thisThe Zen of Python, by Tim Peters
Beautiful is better than ugly.Explicit is better than implicit.Simple is better than complex.Complex is better than complicated.Flat is better than nested.Sparse is better than dense.Readability counts.Special cases aren't special enough to break the rules.Although practicality beats purity.Errors should never pass silently.Unless explicitly silenced.In the face of ambiguity, refuse the temptation to guess.There should be one-- and preferably only one --obvious way to do it.Although that way may not be obvious at first unless you're Dutch.Now is better than never.Although never is often better than *right* now.If the implementation is hard to explain, it's a bad idea.If the implementation is easy to explain, it may be a good idea.Namespaces are one honking great idea -- let's do more of those!
![Page 22: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/22.jpg)
>>> import thisThe Zen of Python, by Tim Peters
Beautiful is better than ugly.Explicit is better than implicit.Simple is better than complex.Complex is better than complicated.Flat is better than nested.Sparse is better than dense.Readability counts.Special cases aren't special enough to break the rules.Although practicality beats purity.Errors should never pass silently.Unless explicitly silenced.In the face of ambiguity, refuse the temptation to guess.There should be one-- and preferably only one --obvious way to do it.Although that way may not be obvious at first unless you're Dutch.Now is better than never.Although never is often better than *right* now.If the implementation is hard to explain, it's a bad idea.If the implementation is easy to explain, it may be a good idea.Namespaces are one honking great idea -- let's do more of those!
![Page 23: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/23.jpg)
Python 3Immutable 'bytes' typeStrings/unicodeprint()raw_input
![Page 24: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/24.jpg)
Python in macOS?"Future versions of macOS won't include scripting language runtimes by default, and might require you to install additional packages. If your software depends on scripting languages, it's recommended that you bundle the runtime within the app."https://developer.apple.com/documentation/macos_release_notes/macos_catalina_10_15_beta_2_release_notes
![Page 25: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/25.jpg)
Relocatable pyhttps://github.com/gregneagle/relocatable-python Custom python frameworkIncludes PyObjCPython3
@gregneagle
![Page 26: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/26.jpg)
![Page 27: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/27.jpg)
Types
![Page 28: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/28.jpg)
str- Single/double quotes- Backslash escapes- Immutable
>>> appetizer = 'spam'
>>> dinner = "spam \
spam"
>>> dessert = appetizer*3
'spamspamspam'
![Page 29: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/29.jpg)
str methods- s.lower(), s.upper()- s.startswith()- s.replace()- s.strip()
>>> s = 'spam'
>>> s.upper()
'SPAM'
>>> s.startswith('ham')
False
>>>s.replace('spam','eggs')
'eggs'
![Page 30: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/30.jpg)
str methods- s.split()
>>> s = 'cleese idle chapman palin jones'
>>> s.split()
['cleese', 'idle', 'chapman', 'palin', 'jones']
![Page 31: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/31.jpg)
Combining methods
>>> always_look.strip().split('\n')
[
"When you're feeling in the dumps,",
"Don't be silly chumps,",
"Just purse your lips and whistle -- that's the thing!",
'And... always look on the bright side of life...'
]
![Page 32: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/32.jpg)
str slices- s[start:end]
>>> s = 'fleshwound'
>>> s[:5]
'flesh'
>>> s[-5:]
'wound'
>>> s[5:]
'wound'
>>> s[3:7]
'shwo'
![Page 33: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/33.jpg)
String interpolation
Old style:
>>> "That's %s with two Ks," % (author)
"That's Dikkens with two Ks,"
---
New style:
>>> "the well-known {} author.".format(nationality)
'the well-known Dutch author.'
![Page 34: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/34.jpg)
int- >>> type(12)
<class 'int'>
>>> num = 12
>>> num + 12
24
>>> num > 13
False
![Page 35: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/35.jpg)
Integer operationsx + y Sum of x and y
x - y Difference of x and y
x * y Product of x and y
x / y Quotient of x and y
x // y Quotient from floor division of x and y
x % y Remainder of x / y
x ** y x to the y power
(https://www.digitalocean.com/community/tutorials/how-to-do-math-in-python-3-with-operators)
![Page 36: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/36.jpg)
floats- >>> type(12.0)
<class 'float'>
>>> num = 12
>>> num / 5
2
>>> num = 12.0
>>> num / 5
2.4
![Page 37: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/37.jpg)
Lists
![Page 38: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/38.jpg)
liststype(['foo','bar'])<type 'list'>
l = [
'Red Leicester', 'Tilsit', 'Gruyere', 'Norwegian Jarlsberger'
]
l.append('Camembert')
l.extend(['Edam','Gouda'])
l.remove('Red Leicester')
![Page 39: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/39.jpg)
list methods- slicing- pop()
>>> l[0]
'Tilsit'
>>> l[-1]
'Gouda'
>>> l.pop()
'Gouda'
>>> l[-1]
'Edam'
![Page 40: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/40.jpg)
list methods- sort()- reverse()
>>> l.sort()
>>> print l
['Camembert', 'Edam', 'Gruyere', 'Norwegian Jarlsberger', 'Tilsit']
>>> l.reverse()
>>> print l
['Tilsit', 'Norwegian Jarlsberger', 'Gruyere', 'Edam', 'Camembert']
![Page 41: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/41.jpg)
list methods- sorted()
>>> li = sorted(l)
>>> l
['Tilsit', 'Gruyere', 'Norwegian Jarlsberger', 'Camembert', 'Edam', 'Gouda']
>>> li
['Camembert', 'Edam', 'Gouda', 'Gruyere', 'Norwegian Jarlsberger', 'Tilsit']
![Page 42: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/42.jpg)
list methods- sorted(reverse=True)- sorted(key=len)- sorted(key=str.lower)
>>> print sorted(l, reverse=True)
['Tilsit', 'Norwegian Jarlsberger', 'Gruyere', 'Gouda', 'Edam', 'Camembert']
>>> print sorted(l, key=len)
['Edam', 'Gouda', 'Tilsit', 'Gruyere', 'Camembert', 'Norwegian Jarlsberger']
![Page 43: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/43.jpg)
tuples- type(('foo', 'bar'))
<type 'tuple'>
>>>t = ('Flying Circus', 'Fawlty Towers')
>>>t.append('Blackadder')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'append'
![Page 44: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/44.jpg)
tuples- sorted()
>>> print sorted(t)
['Fawlty Towers', 'Flying Circus']
>>> print sorted(t, reverse=True)
['Flying Circus', 'Fawlty Towers']
![Page 45: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/45.jpg)
sets- s = set(['foo','bar'])- type(s)
<type 'set'>
>>> s = set(['graham', 'john', 'terry', 'michael', 'eric', 'terry'])
>>> print s
set(['michael', 'john', 'graham', 'eric', 'terry'])
![Page 46: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/46.jpg)
Dictionaries
![Page 47: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/47.jpg)
dictionaries- type({'foo': 'bar'})
<type 'dict'>
>>> d = {
'Philosophers':
['Kant', 'Plato', 'Mill', 'Hume']
}
>>>print d['Philosophers']
['Kant', 'Plato', 'Mill', 'Hume']
![Page 48: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/48.jpg)
dictionariesd[key] = value
>>> d['Philosophers'][0]
Kant
>>> print d.get('boozy beggar', 'Heidegger')
Heidegger
![Page 49: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/49.jpg)
dictionariesd.keys()d.values()
>>> d.keys()
['Philosophers', 'Drinks']
>>> d.values()
[['Socrates', 'Wittgenstein', 'Nietzche', 'Hobbes'], ['Beer', 'Shandy', 'Whiskey', 'Dram']]
![Page 50: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/50.jpg)
loops- FOR and IN- d.items()
>>> for k, v in d.items():
... print k
... print v
Philosophers
['Socrates', 'Wittgenstein', 'Nietzche', 'Hobbes']
Drinks
['Beer', 'Shandy', 'Whiskey', 'Dram']
![Page 51: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/51.jpg)
loops- FOR and IN
>>> for movie in movies:
... print movie
...
Meaning of Life
Holy Grail
Life of Brian
Live at the Hollywood Bowl
![Page 52: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/52.jpg)
list comprehensions- [x for i in l]
>>> import math
>>> nums = [1, 4, 9, 16]
>>> squares = [ math.sqrt(n) for n in nums ]
>>> squares
[1.0, 2.0, 3.0, 4.0]
![Page 53: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/53.jpg)
Booleans
![Page 54: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/54.jpg)
booleans- Truth·i·ness
The quality of seeming or being felt to be true, even if not necessarily true. https://en.wikipedia.org/wiki/Truthiness
![Page 55: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/55.jpg)
booleans- >>> bool(True)
True
>>> True and True
True
>>> True and False
False
![Page 56: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/56.jpg)
booleans- >>> bool(False)
False
>>> True and True
True
>>> True and False
False
>>> False and False
![Page 57: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/57.jpg)
booleans- >>> bool(False)
False
>>> True and True
True
>>> True and False
False
>>> False and False
False
![Page 58: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/58.jpg)
Modules
![Page 59: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/59.jpg)
functions- >>> def foo(args):
>>> def add_em_up(x, y):
... return x + y
>>> add_em_up(13, 5)
18
>>> add_em_up(-8, 53)
45
![Page 60: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/60.jpg)
built-in methods- os- subprocess- json- plistlib
>>> import os
>>>os.path.exists('/')
True
![Page 61: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/61.jpg)
os>>> import os>>> path = '~/Library/Preferences/com.trusourcelabs.NoMAD.plist'>>> os.path.exists(path)
![Page 62: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/62.jpg)
os>>> import os>>> path = '~/Library/Preferences/com.trusourcelabs.NoMAD.plist'>>> os.path.exists(path)False
![Page 63: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/63.jpg)
os>>> import os>>> path = '~/Library/Preferences/com.trusourcelabs.NoMAD.plist'>>> os.path.exists(os.path.expanduser(path))
![Page 64: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/64.jpg)
os>>> import os>>> path = '~/Library/Preferences/com.trusourcelabs.NoMAD.plist'>>> os.path.exists(os.path.expanduser(path))True
![Page 65: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/65.jpg)
os>>> import os>>> path = '~/Library/Preferences/com.trusourcelabs.NoMAD.plist'>>> os.path.exists(os.path.expanduser(path))True
>>> os.path.basename(os.path.expanduser(path))
>>> os.path.dirname(os.path.expanduser(path))
![Page 66: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/66.jpg)
os>>> import os>>> path = '~/Library/Preferences/com.trusourcelabs.NoMAD.plist'>>> os.path.exists(os.path.expanduser(path))True
>>> os.path.basename(os.path.expanduser(path))'com.trusourcelabs.NoMAD.plist'>>> os.path.dirname(os.path.expanduser(path))'/Users/chilcote/Library/Preferences'
![Page 67: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/67.jpg)
os>>> import os>>> path = '~/Library/Preferences/com.trusourcelabs.NoMAD.plist'>>> os.path.exists(os.path.expanduser(path))True
>>> os.path.basename(os.path.expanduser(path))'com.trusourcelabs.NoMAD.plist'>>> os.path.dirname(os.path.expanduser(path))'/Users/chilcote/Library/Preferences'
path_dir = '/Users/chilcote/Library/Preferences'path_file = 'com.trusourcelabs.NoMAD.plist'
![Page 68: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/68.jpg)
os>>> import os>>> path = '~/Library/Preferences/com.trusourcelabs.NoMAD.plist'>>> os.path.exists(os.path.expanduser(path))True
>>> os.path.basename(os.path.expanduser(path))'com.trusourcelabs.NoMAD.plist'>>> os.path.dirname(os.path.expanduser(path))'/Users/chilcote/Library/Preferences'
path_dir = '/Users/chilcote/Library/Preferences'path_file = 'com.trusourcelabs.NoMAD.plist'
pathname = os.path.join(path_dir, path_file)
![Page 69: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/69.jpg)
os>>> import os>>> path = '~/Library/Preferences/com.trusourcelabs.NoMAD.plist'>>> os.path.exists(os.path.expanduser(path))True
>>> os.path.basename(os.path.expanduser(path))'com.trusourcelabs.NoMAD.plist'>>> os.path.dirname(os.path.expanduser(path))'/Users/chilcote/Library/Preferences'
path_dir = '/Users/chilcote/Library/Preferences'path_file = 'com.trusourcelabs.NoMAD.plist'
pathname = os.path.join(path_dir, path_file)
>>> pathname'/Users/chilcote/Library/Preferences/com.trusourcelabs.NoMAD.plist'
![Page 70: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/70.jpg)
os>>> path = os.path.expanduser('~/Desktop/myfiles')>>> for pathname in os.listdir(path):... print(pathname)... another filedon't forget this file over heresomefile
![Page 71: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/71.jpg)
subprocess>>> import subprocess>>> subprocess.check_output(['uname', '-a'])'Darwin chilcote-mbptb 19.0.0 Darwin Kernel Version 19.0.0: Thu Jun 27 20:18:24 PDT 2019; root:xnu-6153.0.13.131.3~1/RELEASE_X86_64 x86_64\n'
![Page 72: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/72.jpg)
subprocess>>> import subprocess>>> subprocess.check_output(['exit', '1'])Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 216, in check_output process = Popen(stdout=PIPE, *popenargs, **kwargs) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 394, in __init__ errread, errwrite) File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1047, in _execute_child raise child_exception
![Page 73: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/73.jpg)
subprocess>>> import subprocess>>> try:... subprocess.check_output(['exit', '1'])... except:... print('check yourself')... check yourself
![Page 74: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/74.jpg)
subprocess>>> import subprocess>>> cmd = ['sysctl', '-n', 'hw.model']>>> task = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
![Page 75: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/75.jpg)
subprocess>>> import subprocess>>> cmd = ['sysctl', '-n', 'hw.model']>>> task = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)>>> out, err = task.communicate()>>> out'MacBookPro15,1\n'>>> err''
![Page 76: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/76.jpg)
json>>> import json>>> template = '/Library/vfuse/Mojave.json'>>> if os.path.exists(template):... with open(template) as f:... d = json.load(f)...
![Page 77: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/77.jpg)
json>>> import json>>> template = '/Library/vfuse/Mojave.json'>>> if os.path.exists(template):... with open(template) as f:... d = json.load(f)... >>> print(d){u'qemu_path': u'/opt/local/bin/qemu-img', u'use_qemu': True, u'logger_file': u'/var/log/cpe_logger.log', u'cache': True, u'source_dmg': u'https://example.com/vms/osx-10.14.5-18F203.apfs.dmg', u'serial_number': u'random', u'output_name': u'Mojave', u'snapshot': True}
![Page 78: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/78.jpg)
json>>> import json>>> template = '/Library/vfuse/Mojave.json'>>> if os.path.exists(template):... with open(template) as f:... d = json.load(f)... >>> print(d){u'qemu_path': u'/opt/local/bin/qemu-img', u'use_qemu': True, u'logger_file': u'/var/log/cpe_logger.log', u'cache': True, u'source_dmg': u'https://example.com/vms/osx-10.14.5-18F203.apfs.dmg', u'serial_number': u'random', u'output_name': u'Mojave', u'snapshot': True}
>>> d['snapshot'] = False>>> new_template = '/Users/Shared/Mojave.json'>>> with open(new_template, 'w') as f:... json.dump(d, f, indent=4, separators=(",", ": "))
![Page 79: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/79.jpg)
plistlib>>> import plistlib>>> d = plistlib.readPlist('/Applications/Firefox.app/Contents/Info.plist')>>> d['CFBundleShortVersionString']'67.0.4'
![Page 80: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/80.jpg)
plistlib>>> import plistlib>>> d = plistlib.readPlist('/Applications/Firefox.app/Contents/Info.plist')>>> d['CFBundleShortVersionString']'67.0.4'
>>> print(d){'LSEnvironment': {'MallocNanoZone': '0'}, 'CFBundleInfoDictionaryVersion': '6.0', 'MozillaDeveloperObjPath': '/builds/worker/workspace/build/src/obj-firefox', 'CFBundleGetInfoString': 'Firefox 67.0.4', 'CFBundleIdentifier': 'org.mozilla.firefox', 'CFBundleDocumentTypes': [{'CFBundleTypeName': 'HTML Document', 'CFBundleTypeOSTypes': ['HTML'], 'CFBundleTypeRole': 'Viewer', 'CFBundleTypeIconFile': 'document.icns', 'CFBundleTypeExtensions': ['html', 'htm', 'shtml', 'xht', 'xhtml']}, {'CFBundleTypeRole': 'Viewer', 'CFBundleTypeIconFile': 'document.icns', 'CFBundleTypeExtensions': ['json'], 'CFBundleTypeName': 'JSON File', 'CFBundleTypeMIMETypes': ['application/json'], 'CFBundleTypeOSTypes': ['TEXT']}, {'CFBundleTypeRole': 'Viewer',
![Page 81: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/81.jpg)
built-in methods- argparse()- logging()
>>> import os
>>>os.path.exists('/')
True
![Page 82: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/82.jpg)
argparse>>> import argparse
>>> parser = argparse.ArgumentParser(description='Making arguments')>>> parser.add_argument('--list', '-l', action='store_true',>>> help='list categories')>>> parser.add_argument('--version', '-v', action='store_true',>>> help='show the version number')>>> parser.add_argument('--json', action='append', nargs='*', metavar='',>>> help='return in json format')>>> parser.add_argument('--quiet', '-q', action='append', nargs='*', metavar='',>>> help='suppress output')>>> parser.add_argument('remnants', action='append', nargs=argparse.REMAINDER)>>> args = parser.parse_args()
![Page 83: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/83.jpg)
argparse>>> import argparse
>>> parser = argparse.ArgumentParser(description='Making arguments')>>> parser.add_argument('--list', '-l', action='store_true',>>> help='list categories')>>> parser.add_argument('--version', '-v', action='store_true',>>> help='show the version number')>>> parser.add_argument('--json', action='append', nargs='*', metavar='',>>> help='return in json format')>>> parser.add_argument('--quiet', '-q', action='append', nargs='*', metavar='',>>> help='suppress output')>>> parser.add_argument('remnants', action='append', nargs=argparse.REMAINDER)>>> args = parser.parse_args()
![Page 84: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/84.jpg)
logging>>> import logging
>>> log_file = '/var/log/myscriptsneverfail.log'>>> logging.basicConfig(>>> format='%(asctime)s - %(levelname)s: %(message)s',>>> datefmt='%Y-%m-%d %I:%M:%S %p',>>> level=logging.DEBUG,>>> filename=log_file)>>> stdout_logging = logging.StreamHandler()>>> stdout_logging.setFormatter(logging.Formatter())>>> logging.getLogger().addHandler(stdout_logging)
![Page 85: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/85.jpg)
logging>>> import logging
>>> log_file = '/var/log/myscriptsneverfail.log'>>> logging.basicConfig(>>> format='%(asctime)s - %(levelname)s: %(message)s',>>> datefmt='%Y-%m-%d %I:%M:%S %p',>>> level=logging.DEBUG,>>> filename=log_file)>>> stdout_logging = logging.StreamHandler()>>> stdout_logging.setFormatter(logging.Formatter())>>> logging.getLogger().addHandler(stdout_logging)
![Page 86: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/86.jpg)
logging>>> import logging
>>> log_file = '/var/log/myscriptsneverfail.log'>>> logging.basicConfig(>>> format='%(asctime)s - %(levelname)s: %(message)s',>>> datefmt='%Y-%m-%d %I:%M:%S %p',>>> level=logging.DEBUG,>>> filename=log_file)>>> stdout_logging = logging.StreamHandler()>>> stdout_logging.setFormatter(logging.Formatter())>>> logging.getLogger().addHandler(stdout_logging)
>>> logging.debug('Model: %s', get_hardwaremodel())>>> logging.debug('Serial: %s', get_serialnumber())>>> logging.debug('OS: %s', get_osversion())>>> logging.debug('Build: %s', get_buildversion())
![Page 87: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/87.jpg)
loggingLog levels: DEBUG: shows CRITICAL, ERROR, WARNING, INFO, DEBUG INFO: shows CRITICAL, ERROR, WARNING, INFO WARNING: shows CRITICAL, ERROR, WARNING ERROR: shows CRITICAL, ERROR CRITICAL: shows CRITICAL
Default (no arguments) is WARNING
![Page 88: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/88.jpg)
from argparse import ArgumentParserimport logging
parser = ArgumentParser(description="Foo app")parser.add_argument('-ll', '--loglevel', type=str, choices=['DEBUG','INFO','WARNING','ERROR','CRITICAL'], help='Set the logging level')args = parser.parse_args()logging.basicConfig(level=args.loglevel)
logger = logging.getLogger()
![Page 89: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/89.jpg)
from argparse import ArgumentParserimport logging
parser = ArgumentParser(description="Foo app")parser.add_argument('-ll', '--loglevel', type=str, choices=['DEBUG','INFO','WARNING','ERROR','CRITICAL'], help='Set the logging level')args = parser.parse_args()logging.basicConfig(level=args.loglevel)
logger = logging.getLogger()
logger.debug('foo debug message')logger.info('foo info message')logger.warning('foo warning message')logger.error('foo error message')logger.critical('foo critical message')
![Page 90: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/90.jpg)
% ./logger.py --loglevel DEBUGDEBUG:root:foo debug messageINFO:root:foo info messageWARNING:root:foo warning messageERROR:root:foo error messageCRITICAL:root:foo critical message
![Page 91: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/91.jpg)
% ./logger.py --loglevel DEBUGDEBUG:root:foo debug messageINFO:root:foo info messageWARNING:root:foo warning messageERROR:root:foo error messageCRITICAL:root:foo critical message% ./logger.py --loglevel INFO INFO:root:foo info messageWARNING:root:foo warning messageERROR:root:foo error messageCRITICAL:root:foo critical message
![Page 92: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/92.jpg)
% ./logger.py --loglevel DEBUGDEBUG:root:foo debug messageINFO:root:foo info messageWARNING:root:foo warning messageERROR:root:foo error messageCRITICAL:root:foo critical message% ./logger.py --loglevel INFO INFO:root:foo info messageWARNING:root:foo warning messageERROR:root:foo error messageCRITICAL:root:foo critical message% ./logger.py --loglevel WARNINGWARNING:root:foo warning messageERROR:root:foo error messageCRITICAL:root:foo critical message% ./logger.py --loglevel ERROR ERROR:root:foo error messageCRITICAL:root:foo critical message
![Page 93: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/93.jpg)
% ./logger.py --loglevel DEBUGDEBUG:root:foo debug messageINFO:root:foo info messageWARNING:root:foo warning messageERROR:root:foo error messageCRITICAL:root:foo critical message% ./logger.py --loglevel INFO INFO:root:foo info messageWARNING:root:foo warning messageERROR:root:foo error messageCRITICAL:root:foo critical message% ./logger.py --loglevel WARNINGWARNING:root:foo warning messageERROR:root:foo error messageCRITICAL:root:foo critical message% ./logger.py --loglevel ERROR ERROR:root:foo error messageCRITICAL:root:foo critical message% ./logger.py --loglevel CRITICALCRITICAL:root:foo critical message
![Page 94: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/94.jpg)
Example time!
![Page 95: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/95.jpg)
from random import choice, randint
def get_songtitle(wordcount, words): songtitle = [] for i in range(1, wordcount): songtitle.append(choice(words).title().strip()) while True: char_count = len(' '.join(songtitle)) if char_count <= 114: break songtitle.pop() return ' '.join(songtitle)
def main(): with open('/usr/share/dict/words', 'r') as f: words = f.readlines() bob_sez = 'My favorite GBV song is %s!' % get_songtitle(randint(4, 17), words) print bob_sez
if __name__ == "__main__": main()
![Page 96: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/96.jpg)
from random import choice, randint
def get_songtitle(wordcount, words): songtitle = [] for i in range(1, wordcount): songtitle.append(choice(words).title().strip()) while True: char_count = len(' '.join(songtitle)) if char_count <= 114: break songtitle.pop() return ' '.join(songtitle)
def main(): with open('/usr/share/dict/words', 'r') as f: words = f.readlines() bob_sez = 'My favorite GBV song is %s!' % get_songtitle(randint(4, 17), words) print bob_sez
if __name__ == "__main__": main() https://github.com/chilcote/gbv
![Page 97: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/97.jpg)
from random import choice, randint
def get_songtitle(wordcount, words): songtitle = [] for i in range(1, wordcount): songtitle.append(choice(words).title().strip()) while True: char_count = len(' '.join(songtitle)) if char_count <= 114: break songtitle.pop() return ' '.join(songtitle)
def main(): with open('/usr/share/dict/words', 'r') as f: words = f.readlines() bob_sez = 'My favorite GBV song is %s!' % get_songtitle(randint(4, 17), words) print bob_sez
if __name__ == "__main__": main() https://github.com/chilcote/gbv
![Page 98: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/98.jpg)
from random import choice, randint
def get_songtitle(wordcount, words): songtitle = [] for i in range(1, wordcount): songtitle.append(choice(words).title().strip()) while True: char_count = len(' '.join(songtitle)) if char_count <= 114: break songtitle.pop() return ' '.join(songtitle)
def main(): with open('/usr/share/dict/words', 'r') as f: words = f.readlines() bob_sez = 'My favorite GBV song is %s!' % get_songtitle(randint(4, 17), words) print bob_sez
if __name__ == "__main__": main() https://github.com/chilcote/gbv
![Page 99: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/99.jpg)
from random import choice, randint
def get_songtitle(wordcount, words): songtitle = [] for i in range(1, wordcount): songtitle.append(choice(words).title().strip()) while True: char_count = len(' '.join(songtitle)) if char_count <= 114: break songtitle.pop() return ' '.join(songtitle)
def main(): with open('/usr/share/dict/words', 'r') as f: words = f.readlines() bob_sez = 'My favorite GBV song is %s!' % get_songtitle(randint(4, 17), words) print bob_sez
if __name__ == "__main__": main() https://github.com/chilcote/gbv
![Page 100: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/100.jpg)
from random import choice, randint
def get_songtitle(wordcount, words): songtitle = [] for i in range(1, wordcount): songtitle.append(choice(words).title().strip()) while True: char_count = len(' '.join(songtitle)) if char_count <= 114: break songtitle.pop() return ' '.join(songtitle)
def main(): with open('/usr/share/dict/words', 'r') as f: words = f.readlines() bob_sez = 'My favorite GBV song is %s!' % get_songtitle(randint(4, 17), words) print bob_sez
if __name__ == "__main__": main() https://github.com/chilcote/gbv
![Page 101: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/101.jpg)
from random import choice, randint
def get_songtitle(wordcount, words): songtitle = [] for i in range(1, wordcount): songtitle.append(choice(words).title().strip()) while True: char_count = len(' '.join(songtitle)) if char_count <= 114: break songtitle.pop() return ' '.join(songtitle)
def main(): with open('/usr/share/dict/words', 'r') as f: words = f.readlines() bob_sez = 'My favorite GBV song is %s!' % get_songtitle(randint(4, 17), words) print bob_sez
if __name__ == "__main__": main() https://github.com/chilcote/gbv
![Page 102: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/102.jpg)
% ./gbv.pyMy favorite GBV song is Appetence Spitzenburg Calumniatory Antares Armoric Resorcinum Baroness Scogger Tribeship Nashgob Unphilological!% ./gbv.pyMy favorite GBV song is Vesiculotomy Disarchbishop Grudgeful Undervest Digressive Smoothness Enteroplegia Woodjobber!% ./gbv.py My favorite GBV song is Prefreshman Constitutionalism Chevalier Metakinetic Imbondo Perivertebral Glassrope Superobstinate Septocylindrium!% ./gbv.pyMy favorite GBV song is Mailclad Disfeaturement Eremic Encephalopathic Hematometry Isleless Angiorrhagia Pigstick Cistaceae Isoxime!% ./gbv.pyMy favorite GBV song is Proximobuccal Amelu Omarthritis Polymeter Brickcroft Aubrey Indusiated!% ./gbv.pyMy favorite GBV song is Nonspeculative Kaolinize Motherliness Twitterer Trawlerman Shrip Mamelonation Hothouse Locket Mycotrophic Lete!% ./gbv.pyMy favorite GBV song is Hugger Eniac Broadhearted Daimon Interstapedial Upbolt Excrementitiously Fleetingly Debility Colleen Anthophyta!
![Page 103: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/103.jpg)
PyObjC
![Page 104: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/104.jpg)
PyObjC
![Page 105: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/105.jpg)
PyObjC
![Page 106: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/106.jpg)
PyObjC#ref: https://gist.github.com/pudquick/c7dd1262bd81a32663f0
import objcfrom Foundation import NSBundle
IOKit_bundle = NSBundle.bundleWithIdentifier_('com.apple.framework.IOKit')functions = [("IOServiceGetMatchingService", b"II@"),
("IOServiceMatching", b"@*"), ("IORegistryEntryCreateCFProperty", b"@I@@I")]
objc.loadBundleFunctions(IOKit_bundle, globals(), functions)
def io_key(keyname): return IORegistryEntryCreateCFProperty(IOServiceGetMatchingService(0, IOServiceMatching("IOPlatformExpertDevice")), keyname, None, 0)
![Page 107: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/107.jpg)
PyObjC#ref: https://gist.github.com/pudquick/c7dd1262bd81a32663f0
import objcfrom Foundation import NSBundle
IOKit_bundle = NSBundle.bundleWithIdentifier_('com.apple.framework.IOKit')functions = [("IOServiceGetMatchingService", b"II@"),
("IOServiceMatching", b"@*"), ("IORegistryEntryCreateCFProperty", b"@I@@I")]
objc.loadBundleFunctions(IOKit_bundle, globals(), functions)
def io_key(keyname): return IORegistryEntryCreateCFProperty(IOServiceGetMatchingService(0, IOServiceMatching("IOPlatformExpertDevice")), keyname, None, 0)
![Page 108: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/108.jpg)
PyObjC#ref: https://gist.github.com/pudquick/c7dd1262bd81a32663f0
import objcfrom Foundation import NSBundle
IOKit_bundle = NSBundle.bundleWithIdentifier_('com.apple.framework.IOKit')functions = [("IOServiceGetMatchingService", b"II@"),
("IOServiceMatching", b"@*"), ("IORegistryEntryCreateCFProperty", b"@I@@I")]
objc.loadBundleFunctions(IOKit_bundle, globals(), functions)
def io_key(keyname): return IORegistryEntryCreateCFProperty(IOServiceGetMatchingService(0, IOServiceMatching("IOPlatformExpertDevice")), keyname, None, 0)
print io_key("IOPlatformUUID")print io_key("IOPlatformSerialNumber")
![Page 109: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/109.jpg)
PyObjC- Preference domains- Device info- User info
>>> import CoreFoundation
>>> import SystemConfiguration
![Page 110: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/110.jpg)
CoreFoundationfrom CoreFoundation import ( CFPreferencesCopyAppValue, CFPreferencesAppValueIsForced )
![Page 111: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/111.jpg)
CoreFoundationfrom CoreFoundation import ( CFPreferencesCopyAppValue, CFPreferencesAppValueIsForced )
domain = '/Library/Preferences/com.apple.SoftwareUpdate'key = 'AutomaticCheckEnabled'
key_value = CFPreferencesCopyAppValue(key, domain)print 'Key Value: %s' % key_value
key_forced = CFPreferencesAppValueIsForced(key, domain)print 'Key Forced: %s' % key_forced
![Page 112: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/112.jpg)
CoreFoundationfrom CoreFoundation import ( CFPreferencesCopyAppValue, CFPreferencesAppValueIsForced )
domain = '/Library/Preferences/com.apple.SoftwareUpdate'key = 'AutomaticCheckEnabled'
key_value = CFPreferencesCopyAppValue(key, domain)print 'Key Value: %s' % key_value
key_forced = CFPreferencesAppValueIsForced(key, domain)print 'Key Forced: %s' % key_forced
Key Value: TrueKey Forced: True
![Page 113: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/113.jpg)
CoreFoundation
![Page 114: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/114.jpg)
CoreFoundationFrom CoreFoundation import ( CFPreferencesCopyKeyList,
kCFPreferencesCurrentUser, kCFPreferencesCurrentHost
)
print CFPreferencesCopyKeyList('/Library/Preferences/com.apple.SoftwareUpdate', kCFPreferencesCurrentUser, kCFPreferencesCurrentHost)
![Page 115: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/115.jpg)
( EvaluateCriticalEvenIfUnchanged, RecommendedUpdates, OneTimeForceScanEnabled, LastResultCode, AutomaticallyInstallMacOSUpdates, InactiveUpdates, SkipLocalCDN, LastAttemptBuildVersion, AutomaticDownload, LastAttemptSystemVersion, LastFullSuccessfulDate, LastCatalogChangeDate, LastSuccessfulDate, CriticalUpdateInstall, LastRecommendedUpdatesAvailable, ConfigDataInstall, LastUpdatesAvailable, AutomaticCheckEnabled, LastBackgroundSuccessfulDate, PrimaryLanguages, LastSessionSuccessful)
![Page 116: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/116.jpg)
SystemConfigurationfrom SystemConfiguration import SCDynamicStoreCreate, SCDynamicStoreCopyValue
factoid = 'hostname'
def fact(): '''Returns the value of the hostname of this Mac''' result = 'None'
net_config = SCDynamicStoreCreate(None, "net", None, None) sys_info = SCDynamicStoreCopyValue(net_config, "Setup:/System") result = sys_info['HostName']
return {factoid: result}
if __name__ == '__main__': print '<result>%s</result>' % fact()[factoid]
![Page 117: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/117.jpg)
SystemConfigurationfrom SystemConfiguration import SCDynamicStoreCreate, SCDynamicStoreCopyValue
factoid = 'hostname'
def fact(): '''Returns the value of the hostname of this Mac''' result = 'None'
net_config = SCDynamicStoreCreate(None, "net", None, None) sys_info = SCDynamicStoreCopyValue(net_config, "Setup:/System") result = sys_info['HostName']
return {factoid: result}
if __name__ == '__main__': print '<result>%s</result>' % fact()[factoid]
% python ./hostname.py<result>chilcote-mac</result>
![Page 118: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/118.jpg)
from SystemConfiguration import SCDynamicStoreCreate, SCDynamicStoreCopyValue
factoid = 'hostname'
def fact(): '''Returns the value of the hostname of this Mac''' result = 'None'
net_config = SCDynamicStoreCreate(None, "net", None, None) sys_info = SCDynamicStoreCopyValue(net_config, "Setup:/System") result = sys_info['HostName']
return {factoid: result}
if __name__ == '__main__': print '<result>%s</result>' % fact()[factoid]
% python ./hostname.py<result>chilcote-mac</result>
![Page 119: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/119.jpg)
from SystemConfiguration import SCDynamicStoreCreate, SCDynamicStoreCopyValue
factoid = 'hostname'
def fact(): '''Returns the value of the hostname of this Mac''' result = 'None'
net_config = SCDynamicStoreCreate(None, "net", None, None) sys_info = SCDynamicStoreCopyValue(net_config, "Setup:/System") result = sys_info['HostName']
return {factoid: result}
if __name__ == '__main__': print '<result>%s</result>' % fact()[factoid]
https://stackoverflow.com/questions/419163/what-does-if-name-main-do
![Page 120: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/120.jpg)
Bringing it all together
![Page 121: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/121.jpg)
Unearth https://github.com/chilcote/unearthimport re, subprocess
def fact(): result = 'None'
try: proc = subprocess.Popen( ['/usr/bin/pmset', '-g', 'batt'], stdout=subprocess.PIPE, stderr=subprocess.PIPE ) stdout, _ = proc.communicate() if stdout: if 'InternalBattery' in stdout: result = re.findall(r'\d+%', stdout.splitlines()[1])[0].replace('%','') except (IOError, OSError): pass
return {factoid: result}
if __name__ == '__main__': print '<result>%s</result>' % fact()[factoid]
![Page 122: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/122.jpg)
Unearth https://github.com/chilcote/unearthfrom SystemConfiguration import SCDynamicStoreCopyConsoleUserimport plistlib, subprocess
factoid = 'console_user_is_admin'
def fact(): '''Returns whether current console user is an admin''' result = False
cmd = ['/usr/bin/dscl', '-plist', '.', 'read', '/Groups/admin'] output = subprocess.check_output(cmd) d = plistlib.readPlistFromString(output)['dsAttrTypeStandard:GroupMembership']
console_user = SCDynamicStoreCopyConsoleUser(None, None, None)[0] if console_user in d: result = True
return {factoid: result}
if __name__ == '__main__': print '<result>%s</result>' % fact()[factoid]
![Page 123: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/123.jpg)
Unearth https://github.com/chilcote/unearth% ./unearth battery_percentage battery_percentage => 97% ./unearth console_user_is_adminconsole_user_is_admin => True
![Page 124: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/124.jpg)
Unearth https://github.com/chilcote/unearth% ./unearth battery_percentage battery_percentage => 97% ./unearth console_user_is_adminconsole_user_is_admin => True
% ./unearth --jss battery_percentage<result>96</result>% ./unearth --jss console_user_is_admin<result>True</result>
![Page 125: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/125.jpg)
Unearth https://github.com/chilcote/unearth% ./unearth battery_percentage battery_percentage => 97% ./unearth console_user_is_adminconsole_user_is_admin => True
% ./unearth --jss battery_percentage<result>96</result>% ./unearth --jss console_user_is_admin<result>True</result>
% ./unearth battery_percentage console_user_is_adminbattery_percentage => 94console_user_is_admin => True
![Page 126: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/126.jpg)
Unearth https://github.com/chilcote/unearth>>> from excavate import Excavate>>> artifacts = Excavate()>>> battery = artifacts.get(['battery_percentage'])>>> if battery['battery_percentage'] <= 20:... print('Skipping Office install due to battery being less than 20%')...
![Page 127: Python 101 - MacAdmins Conference | Join us 6/3](https://reader031.fdocuments.in/reader031/viewer/2022012102/6169f50011a7b741a34d3e03/html5/thumbnails/127.jpg)
Q&AWED 8-11PM - Python 3 Convert-a-thon (Hacker’s Cabin)THU 1:30PM - Impractical Python file and data for today's Mac admins
https://en.wikipedia.org/wiki/Zen_of_Pythonhttps://greenteapress.com/wp/think-python/https://developers.google.com/edu/python/https://docs.python-guide.org/https://learnxinyminutes.com/docs/python/
macadmins.org #python-beginners