├── 12exercises.py ├── db_itunes.py ├── db_sqlite.py ├── game.py ├── hanger_game.py ├── image_server.py ├── json_api.py ├── json_pr.py ├── many_to_many_sql.py ├── oauth.py ├── parser.py ├── pi_estimate.py ├── regex.py ├── rhyming_master.py ├── server.py ├── soup1.py ├── soup2.py ├── test_download.py ├── tuples.py ├── tuples1.py ├── twitter.py ├── twurl.py ├── wheel_game.py └── xml_samples.py /12exercises.py: -------------------------------------------------------------------------------- 1 | # number 1 & 2 2 | 3 | import urllib.request, urllib.parse, urllib.error 4 | from bs4 import BeautifulSoup 5 | import ssl 6 | import socket 7 | 8 | # url = str(input()) 9 | # host = url.split('/') 10 | # print(host) 11 | # cmd = f'GET {url} HTTP/1.0\r\n\r\n' 12 | # counter = 0 13 | # try: 14 | # mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 15 | # mysock.connect((host[2], 80)) 16 | # cmd = cmd.encode() 17 | # mysock.send(cmd) 18 | # 19 | # 20 | # while True: 21 | # data = mysock.recv(512) 22 | # counter += len(data) 23 | # if not data: 24 | # break 25 | # if counter < 1000: 26 | # print(data.decode(), end='') 27 | # 28 | # except OSError: 29 | # print('Make sure URL is correct') 30 | # except IndexError: 31 | # print('Make sure URL is correct') 32 | # mysock.close() 33 | 34 | # number 3 35 | 36 | 37 | # url = str(input()) 38 | # file_handler = rq.urlopen(url) 39 | # count = 0 40 | # 41 | # for line in file_handler: 42 | # for char in line: 43 | # count += 1 44 | # if count < 3000: 45 | # print(line.decode()) 46 | 47 | # To run this, download the BeautifulSoup zip file 48 | # http://www.py4e.com/code3/bs4.zip 49 | # and unzip it in the same directory as this file 50 | 51 | 52 | 53 | # Ignore SSL certificate errors 54 | ctx = ssl.create_default_context() 55 | ctx.check_hostname = False 56 | ctx.verify_mode = ssl.CERT_NONE 57 | 58 | url = str(input('Enter URL - ')) 59 | html = urllib.request.urlopen(url, context=ctx).read() 60 | soup = BeautifulSoup(html, 'html.parser') 61 | 62 | # Retrieve all of the anchor tags 63 | count = 0 64 | tags = soup('p') 65 | for tag in tags: 66 | count += 1 67 | print(html.decode()) -------------------------------------------------------------------------------- /db_itunes.py: -------------------------------------------------------------------------------- 1 | import xml.etree.ElementTree as ET 2 | import sqlite3 3 | 4 | conn = sqlite3.connect('trackdb.sqlite') 5 | cur = conn.cursor() 6 | 7 | # Make some fresh tables using executescript() 8 | cur.executescript(''' 9 | DROP TABLE IF EXISTS Artist; 10 | DROP TABLE IF EXISTS Album; 11 | DROP TABLE IF EXISTS Track; 12 | DROP TABLE IF EXISTS Genre; 13 | 14 | CREATE TABLE Artist ( 15 | id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, 16 | name TEXT UNIQUE 17 | ); 18 | 19 | CREATE TABLE Genre ( 20 | id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, 21 | name TEXT UNIQUE 22 | ); 23 | 24 | CREATE TABLE Album ( 25 | id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, 26 | artist_id INTEGER, 27 | title TEXT UNIQUE 28 | ); 29 | 30 | CREATE TABLE Track ( 31 | id INTEGER NOT NULL PRIMARY KEY 32 | AUTOINCREMENT UNIQUE, 33 | title TEXT UNIQUE, 34 | album_id INTEGER, 35 | genre_id INTEGER, 36 | len INTEGER, rating INTEGER, count INTEGER 37 | ); 38 | ''') 39 | 40 | fname = input('Enter file name: ') 41 | if len(fname) < 1: fname = 'Library.xml' 42 | 43 | 44 | # Track ID369 45 | # NameAnother One Bites The Dust 46 | # ArtistQueen 47 | def lookup(d, key): 48 | found = False 49 | for child in d: 50 | if found: return child.text 51 | if child.tag == 'key' and child.text == key: 52 | found = True 53 | return None 54 | 55 | 56 | stuff = ET.parse(fname) 57 | all = stuff.findall('dict/dict/dict') 58 | print('Dict count:', len(all)) 59 | for entry in all: 60 | if lookup(entry, 'Track ID') is None: continue 61 | 62 | name = lookup(entry, 'Name') 63 | artist = lookup(entry, 'Artist') 64 | album = lookup(entry, 'Album') 65 | count = lookup(entry, 'Play Count') 66 | rating = lookup(entry, 'Rating') 67 | length = lookup(entry, 'Total Time') 68 | # adding genre code 69 | 70 | genre = lookup(entry, 'Genre') 71 | 72 | if name is None or artist is None or album is None or genre is None: 73 | continue 74 | 75 | print(name, artist, album, genre, count, rating, length) 76 | 77 | cur.execute('''INSERT OR IGNORE INTO GENRE (name) 78 | VALUES ( ? )''', (genre,)) 79 | cur.execute('SELECT id FROM Genre WHERE name = ? ', (genre,)) 80 | genre_id = cur.fetchone()[0] 81 | 82 | cur.execute('''INSERT OR IGNORE INTO Artist (name) 83 | VALUES ( ? )''', (artist,)) 84 | cur.execute('SELECT id FROM Artist WHERE name = ? ', (artist,)) 85 | artist_id = cur.fetchone()[0] 86 | 87 | cur.execute('''INSERT OR IGNORE INTO Album (title, artist_id) 88 | VALUES ( ?, ? )''', (album, artist_id)) 89 | cur.execute('SELECT id FROM Album WHERE title = ? ', (album,)) 90 | album_id = cur.fetchone()[0] 91 | 92 | cur.execute('''INSERT OR REPLACE INTO Track 93 | (title, album_id, genre_id, len, rating, count) 94 | VALUES ( ?, ?, ?, ?, ?, ? )''', 95 | (name, album_id, genre_id, length, rating, count)) 96 | 97 | conn.commit() 98 | -------------------------------------------------------------------------------- /db_sqlite.py: -------------------------------------------------------------------------------- 1 | import sqlite3 2 | 3 | conn = sqlite3.connect('emaildb.sqlite') 4 | cur = conn.cursor() 5 | 6 | cur.execute('DROP TABLE IF EXISTS Counts') 7 | 8 | cur.execute('''CREATE TABLE Counts (org TEXT, count INTEGER)''') 9 | 10 | fname = 'mbox.txt' 11 | fh = open(fname) 12 | for line in fh: 13 | if not line.startswith('From: '): continue 14 | pieces = line.split() 15 | email = pieces[1] 16 | org = email.split('@')[1] 17 | cur.execute('SELECT count FROM Counts WHERE org = ? ', (org,)) 18 | row = cur.fetchone() 19 | if row is None: 20 | cur.execute('''INSERT INTO Counts (org, count) 21 | VALUES (?, 1)''', (org,)) 22 | else: 23 | cur.execute('UPDATE Counts SET count = count + 1 WHERE org = ?', 24 | (org,)) 25 | conn.commit() 26 | 27 | # https://www.sqlite.org/lang_select.html 28 | sqlstr = 'SELECT org, count FROM Counts ORDER BY count DESC LIMIT 10' 29 | 30 | for row in cur.execute(sqlstr): 31 | print(str(row[0]), row[1]) 32 | 33 | cur.close() -------------------------------------------------------------------------------- /game.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | import random 3 | import pygame_textinput 4 | 5 | WHITE = (255, 255, 255) 6 | BLACK = (0, 0, 0) 7 | pygame.init() 8 | font = pygame.font.SysFont("georgia", 24) 9 | 10 | 11 | # getting word from file 12 | def pick_word(difficulty, filename='10000_words.txt'): 13 | with open(filename, 'r') as file: 14 | words = file.readlines() 15 | interesting_word = False 16 | 17 | while not interesting_word: 18 | word = random.choice(words) 19 | if len(word) == difficulty: 20 | interesting_word = True 21 | return word 22 | 23 | 24 | clock = pygame.time.Clock() 25 | is_end = False 26 | guessed = [] 27 | die_count = 7 28 | 29 | # pygame.display.set_icon(pygame.image.load('hanger.ico')) 30 | screen = pygame.display.set_mode((600, 500)) 31 | pygame.display.set_caption('Hanger Game') 32 | 33 | text = font.render("Welcome to Hanger game!", 1, WHITE, BLACK) 34 | screen.blit(text, (150, 100)) 35 | 36 | pygame.display.flip() 37 | 38 | def draw_hanger(): 39 | 40 | # drawing foundation 41 | pygame.draw.rect(screen, WHITE, (470, 450, 100, 50)) 42 | # drawing hanger stand 43 | pygame.draw.rect(screen, WHITE, (510, 150, 20, 300)) 44 | # drawing hor bulk 45 | pygame.draw.rect(screen, WHITE, (320, 150, 210, 15)) 46 | pygame.draw.line(screen, WHITE, (460, 155), (520, 190), 5) 47 | # drawing rope 48 | pygame.draw.rect(screen, WHITE, (340, 150, 2, 40)) 49 | pygame.display.flip() 50 | 51 | draw_hanger() 52 | while not is_end: 53 | text_input = pygame_textinput.TextInput(initial_string='Welcome') 54 | 55 | events = pygame.event.get() 56 | for event in events: 57 | if event.type == pygame.QUIT: 58 | exit() 59 | 60 | if event.type == pygame.KEYDOWN: 61 | print('got = ', pygame.key.name(event.key)) 62 | 63 | text_input.update(events) 64 | # Blit its surface onto the screen 65 | if text_input.update(events): 66 | print(text_input.get_text()) 67 | screen.blit(text_input.get_surface(), (10, 10)) 68 | 69 | pygame.display.update() 70 | 71 | clock.tick(60) 72 | -------------------------------------------------------------------------------- /hanger_game.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | import random 3 | 4 | 5 | player = str(input("Enter player name: ")) 6 | 7 | 8 | def pick_word(difficulty, filename='10000_words.txt'): 9 | with open(filename, 'r') as file: 10 | words = file.readlines() 11 | interesting_word = False 12 | 13 | while not interesting_word: 14 | word = random.choice(words) 15 | if len(word) == difficulty: 16 | interesting_word = True 17 | return word 18 | 19 | 20 | def obscure_word(word, guessed): 21 | reveal = '' 22 | for char in word: 23 | if char not in guessed: 24 | reveal += '_' 25 | else: 26 | reveal += char 27 | return reveal 28 | 29 | 30 | def game_round(): 31 | is_end = False 32 | guessed = [] 33 | word = pick_word(int(input('Enter word length: '))) 34 | die_count = 7 35 | 36 | while not is_end and die_count: 37 | 38 | print('Guess this word:') 39 | print(obscure_word(word, guessed)) 40 | print(f'So far tried {guessed}') 41 | print(f'You have {die_count} tries left') 42 | 43 | letter = str(input('Enter your guess, or "Exit" to quit: ')).lower() 44 | print('\n') 45 | 46 | if letter.isalpha() and len(letter) == 1: 47 | if letter in set(guessed): 48 | print("You've tried this one, enter a different letter.") 49 | continue 50 | if letter in word and letter not in guessed: 51 | print(f"Good job {player}, maybe you'll live today..") 52 | guessed.append(letter) 53 | 54 | elif letter == 'Exit': 55 | is_end = True 56 | print('Game over!') 57 | 58 | else: 59 | print('Try again:') 60 | 61 | if word == obscure_word(word, guessed): 62 | is_end = True 63 | print('Congratulations! You have another day to live..') 64 | 65 | if letter not in word: 66 | die_count -= 1 67 | 68 | print('Game over!') 69 | 70 | 71 | print("You have 7 tries to guess the word, otherwise you'll die!\n" 72 | "Good luck!") 73 | 74 | game_round() 75 | -------------------------------------------------------------------------------- /image_server.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import time 3 | 4 | HOST = 'data.pr4e.org' 5 | PORT = 80 6 | new_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 7 | new_socket.connect((HOST, PORT)) 8 | new_socket.sendall(b'GET http://data.pr4e.org/cover3.jpg HTTP/1.0\r\n\r\n') 9 | count = 0 10 | picture = b"" 11 | 12 | while True: 13 | data = new_socket.recv(5120) 14 | if len(data) < 1: break 15 | # time.sleep(0.25) 16 | count = count + len(data) 17 | print(len(data), count) 18 | picture = picture + data 19 | 20 | new_socket.close() 21 | 22 | # Look for the end of the header (2 CRLF) 23 | pos = picture.find(b"\r\n\r\n") 24 | print('Header length', pos) 25 | print(picture[:pos].decode()) 26 | 27 | # Skip past the header and save the picture data 28 | picture = picture[pos + 4:] 29 | file_handler = open("stuff.jpg", "wb") 30 | file_handler.write(picture) 31 | file_handler.close() 32 | -------------------------------------------------------------------------------- /json_api.py: -------------------------------------------------------------------------------- 1 | import urllib.request, urllib.parse, urllib.error 2 | import json 3 | import ssl 4 | 5 | api_key = False 6 | # If you have a Google Places API key, enter it here 7 | # api_key = 'AIzaSy___IDByT70' 8 | # https://developers.google.com/maps/documentation/geocoding/intro 9 | 10 | if api_key is False: 11 | api_key = 42 12 | serviceurl = 'http://py4e-data.dr-chuck.net/json?' 13 | else : 14 | serviceurl = 'https://maps.googleapis.com/maps/api/geocode/json?' 15 | 16 | # Ignore SSL certificate errors 17 | ctx = ssl.create_default_context() 18 | ctx.check_hostname = False 19 | ctx.verify_mode = ssl.CERT_NONE 20 | 21 | while True: 22 | address = input('Enter location: ') 23 | if not address: 24 | break 25 | 26 | parameters = dict() 27 | parameters['address'] = address 28 | if api_key is not False: 29 | parameters['key'] = api_key 30 | url = serviceurl + urllib.parse.urlencode(parameters) 31 | 32 | print('Retrieving', url) 33 | uh = urllib.request.urlopen(url, context=ctx) 34 | data = uh.read().decode() 35 | print('Retrieved', len(data), 'characters') 36 | 37 | try: 38 | js = json.loads(data) 39 | except: 40 | js = None 41 | 42 | if not js or 'status' not in js or js['status'] != 'OK': 43 | print('==== Failure To Retrieve ====') 44 | print(data) 45 | continue 46 | 47 | print(json.dumps(js, indent=4)) 48 | 49 | 50 | try: 51 | print(js['results'][0]['place_id']) 52 | except IndexError: 53 | print('not a country territory') -------------------------------------------------------------------------------- /json_pr.py: -------------------------------------------------------------------------------- 1 | import urllib.request, urllib.parse, urllib.error 2 | import ssl 3 | import json 4 | 5 | 6 | # Ignore SSL certificate errors 7 | ctx = ssl.create_default_context() 8 | ctx.check_hostname = False 9 | ctx.verify_mode = ssl.CERT_NONE 10 | 11 | 12 | url = 'https://py4e-data.dr-chuck.net/comments_1245985.json' 13 | 14 | data = urllib.request.urlopen(url, context=ctx).read() 15 | eat = json.loads(data) 16 | print(eat) 17 | sum = 0 18 | for each in range(len(eat['comments'])): 19 | sum += (eat['comments'][each]['count']) 20 | print(sum) 21 | -------------------------------------------------------------------------------- /many_to_many_sql.py: -------------------------------------------------------------------------------- 1 | import json 2 | import sqlite3 3 | 4 | conn = sqlite3.connect('rosterdb.sqlite') 5 | cur = conn.cursor() 6 | 7 | cur.execute('DROP TABLE IF EXISTS User') 8 | cur.execute('DROP TABLE IF EXISTS Member') 9 | cur.execute('DROP TABLE IF EXISTS Course') 10 | 11 | cur.executescript(""" 12 | CREATE TABLE User( 13 | id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, 14 | name TEXT UNIQUE 15 | ); 16 | 17 | CREATE TABLE Course( 18 | id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE, 19 | title TEXT UNIQUE 20 | ); 21 | 22 | CREATE TABLE Member( 23 | user_id INTEGER, 24 | course_id INTEGER, 25 | role INTEGER, 26 | PRIMARY KEY (user_id, course_id) 27 | ); 28 | 29 | """) 30 | 31 | str_data = open('roster_data_sample.json').read() 32 | json_data = json.loads(str_data) 33 | 34 | for line in json_data: 35 | name = line[0] 36 | title = line[1] 37 | role = line[2] 38 | 39 | 40 | print(name, title, role) 41 | 42 | cur.execute("INSERT OR IGNORE INTO User(name) VALUES (?) ", (name,)) 43 | cur.execute("SELECT id FROM User WHERE name = ?", (name, )) 44 | user_id = cur.fetchone()[0] 45 | 46 | cur.execute("""INSERT OR IGNORE INTO Course(title) VALUES (?)""", 47 | (title,)) 48 | cur.execute("""SELECT id FROM Course WHERE title = ?""", (title, )) 49 | course_id = cur.fetchone()[0] 50 | 51 | cur.execute("""INSERT OR REPLACE INTO Member 52 | (user_id, course_id, role) VALUES(?, ?, ?)""", (user_id, 53 | course_id, role)) 54 | 55 | conn.commit() 56 | 57 | -------------------------------------------------------------------------------- /oauth.py: -------------------------------------------------------------------------------- 1 | """ 2 | The MIT License 3 | 4 | Copyright (c) 2007 Leah Culver 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | """ 24 | 25 | import cgi 26 | import urllib.request, urllib.parse, urllib.error 27 | import time 28 | import random 29 | import urllib.parse 30 | import binascii 31 | 32 | 33 | VERSION = '1.0' # Hi Blaine! 34 | HTTP_METHOD = 'GET' 35 | SIGNATURE_METHOD = 'PLAINTEXT' 36 | 37 | 38 | class OAuthError(RuntimeError): 39 | """Generic exception class.""" 40 | def __init__(self, message='OAuth error occured.'): 41 | self.mymessage = message 42 | 43 | 44 | def build_authenticate_header(realm=''): 45 | """Optional WWW-Authenticate header (401 error)""" 46 | return {'WWW-Authenticate': 'OAuth realm="%s"' % realm} 47 | 48 | 49 | def escape(s): 50 | """Escape a URL including any /.""" 51 | return urllib.parse.quote(s, safe='~') 52 | 53 | 54 | def _utf8_str(s): 55 | """Convert unicode to utf-8.""" 56 | if isinstance(s, str): 57 | return s.encode("utf-8") 58 | else: 59 | return str(s) 60 | 61 | 62 | def generate_timestamp(): 63 | """Get seconds since epoch (UTC).""" 64 | return int(time.time()) 65 | 66 | 67 | def generate_nonce(length=8): 68 | """Generate pseudorandom number.""" 69 | return ''.join([str(random.randint(0, 9)) for i in range(length)]) 70 | 71 | 72 | class OAuthConsumer(object): 73 | """Consumer of OAuth authentication. 74 | 75 | OAuthConsumer is a data type that represents the identity of the Consumer 76 | via its shared secret with the Service Provider. 77 | 78 | """ 79 | key = None 80 | secret = None 81 | 82 | def __init__(self, key, secret): 83 | self.key = key 84 | self.secret = secret 85 | 86 | 87 | class OAuthToken(object): 88 | """OAuthToken is a data type that represents an End User via either an access 89 | or request token. 90 | 91 | key -- the token 92 | secret -- the token secret 93 | 94 | """ 95 | key = None 96 | secret = None 97 | 98 | def __init__(self, key, secret): 99 | self.key = key 100 | self.secret = secret 101 | 102 | def to_string(self): 103 | return urllib.parse.urlencode({'oauth_token': self.key, 104 | 'oauth_token_secret': self.secret}) 105 | 106 | def from_string(s): 107 | """ Returns a token from something like: 108 | oauth_token_secret=xxx&oauth_token=xxx 109 | """ 110 | params = cgi.parse_qs(s, keep_blank_values=False) 111 | key = params['oauth_token'][0] 112 | secret = params['oauth_token_secret'][0] 113 | return OAuthToken(key, secret) 114 | from_string = staticmethod(from_string) 115 | 116 | def __str__(self): 117 | return self.to_string() 118 | 119 | 120 | class OAuthRequest(object): 121 | """OAuthRequest represents the request and can be serialized. 122 | 123 | OAuth parameters: 124 | - oauth_consumer_key 125 | - oauth_token 126 | - oauth_signature_method 127 | - oauth_signature 128 | - oauth_timestamp 129 | - oauth_nonce 130 | - oauth_version 131 | ... any additional parameters, as defined by the Service Provider. 132 | """ 133 | parameters = None # OAuth parameters. 134 | http_method = HTTP_METHOD 135 | http_url = None 136 | version = VERSION 137 | 138 | def __init__(self, http_method=HTTP_METHOD, 139 | http_url=None, parameters=None): 140 | self.http_method = http_method 141 | self.http_url = http_url 142 | self.parameters = parameters or {} 143 | 144 | def set_parameter(self, parameter, value): 145 | self.parameters[parameter] = value 146 | 147 | def get_parameter(self, parameter): 148 | try: 149 | return self.parameters[parameter] 150 | except: 151 | if parameter == "oauth_token": return None 152 | raise OAuthError('Parameter not found: %s' % parameter) 153 | 154 | def _get_timestamp_nonce(self): 155 | return self.get_parameter('oauth_timestamp'), self.get_parameter( 156 | 'oauth_nonce') 157 | 158 | def get_nonoauth_parameters(self): 159 | """Get any non-OAuth parameters.""" 160 | parameters = {} 161 | for k, v in self.parameters.items(): 162 | # Ignore oauth parameters. 163 | if k.find('oauth_') < 0: 164 | parameters[k] = v 165 | return parameters 166 | 167 | def to_header(self, realm=''): 168 | """Serialize as a header for an HTTPAuth request.""" 169 | auth_header = 'OAuth realm="%s"' % realm 170 | # Add the oauth parameters. 171 | if self.parameters: 172 | for k, v in self.parameters.items(): 173 | if k[:6] == 'oauth_': 174 | auth_header += ', %s="%s"' % (k, escape(str(v))) 175 | return {'Authorization': auth_header} 176 | 177 | def to_postdata(self): 178 | """Serialize as post data for a POST request.""" 179 | return '&'.join(['%s=%s' % (escape(str(k)), escape(str(v))) 180 | for k, v in self.parameters.items()]) 181 | 182 | def to_url(self): 183 | """Serialize as a URL for a GET request.""" 184 | return '%s?%s' % (self.get_normalized_http_url(), self.to_postdata()) 185 | 186 | def get_normalized_parameters(self): 187 | """Return a string that contains the parameters that must be signed.""" 188 | # Chuck - Make a copy of the parameters so we can modify them 189 | params = dict(self.parameters) 190 | try: 191 | # Exclude the signature if it exists. 192 | del params['oauth_signature'] 193 | except: 194 | pass 195 | # Escape key values before sorting. 196 | key_values = [(escape(_utf8_str(k)), escape(_utf8_str(v))) 197 | for k, v in list(params.items())] 198 | # Sort lexicographically, first after key, then after value. 199 | key_values.sort() 200 | # Combine key value pairs into a string. 201 | return '&'.join(['%s=%s' % (k, v) for k, v in key_values]) 202 | 203 | def get_normalized_http_method(self): 204 | """Uppercases the http method.""" 205 | return self.http_method.upper() 206 | 207 | def get_normalized_http_url(self): 208 | """Parses the URL and rebuilds it to be scheme://host/path.""" 209 | parts = urllib.parse.urlparse(self.http_url) 210 | scheme, netloc, path = parts[:3] 211 | # Exclude default port numbers. 212 | if scheme == 'http' and netloc[-3:] == ':80': 213 | netloc = netloc[:-3] 214 | elif scheme == 'https' and netloc[-4:] == ':443': 215 | netloc = netloc[:-4] 216 | return '%s://%s%s' % (scheme, netloc, path) 217 | 218 | def sign_request(self, signature_method, consumer, token): 219 | """Set the signature parameter to the result of build_signature.""" 220 | # Set the signature method. 221 | self.set_parameter('oauth_signature_method', 222 | signature_method.get_name()) 223 | # Set the signature. 224 | self.set_parameter('oauth_signature', 225 | self.build_signature(signature_method, 226 | consumer, token)) 227 | 228 | def build_signature(self, signature_method, consumer, token): 229 | """Calls the build signature method within the signature method.""" 230 | return signature_method.build_signature(self, consumer, token) 231 | 232 | def from_request(http_method, http_url, headers=None, 233 | parameters=None, query_string=None): 234 | """Combines multiple parameter sources.""" 235 | if parameters is None: 236 | parameters = {} 237 | 238 | # Headers 239 | if headers and 'Authorization' in headers: 240 | auth_header = headers['Authorization'] 241 | # Check that the authorization header is OAuth. 242 | if auth_header.index('OAuth') > -1: 243 | auth_header = auth_header.lstrip('OAuth ') 244 | try: 245 | # Get the parameters from the header. 246 | header_params = OAuthRequest._split_header(auth_header) 247 | parameters.update(header_params) 248 | except: 249 | raise OAuthError('Unable to parse OAuth parameters from' 250 | 'Authorization header.') 251 | 252 | # GET or POST query string. 253 | if query_string: 254 | query_params = OAuthRequest._split_url_string(query_string) 255 | parameters.update(query_params) 256 | 257 | # URL parameters. 258 | param_str = urllib.parse.urlparse(http_url)[4] # query 259 | url_params = OAuthRequest._split_url_string(param_str) 260 | parameters.update(url_params) 261 | 262 | if parameters: 263 | return OAuthRequest(http_method, http_url, parameters) 264 | 265 | return None 266 | from_request = staticmethod(from_request) 267 | 268 | def from_consumer_and_token(oauth_consumer, token=None, 269 | http_method=HTTP_METHOD, http_url=None, 270 | parameters=None): 271 | if not parameters: 272 | parameters = {} 273 | 274 | defaults = { 275 | 'oauth_consumer_key': oauth_consumer.key, 276 | 'oauth_timestamp': generate_timestamp(), 277 | 'oauth_nonce': generate_nonce(), 278 | 'oauth_version': OAuthRequest.version, 279 | } 280 | 281 | defaults.update(parameters) 282 | parameters = defaults 283 | 284 | if token: 285 | parameters['oauth_token'] = token.key 286 | 287 | return OAuthRequest(http_method, http_url, parameters) 288 | from_consumer_and_token = staticmethod(from_consumer_and_token) 289 | 290 | def from_token_and_callback(token, callback=None, 291 | http_method=HTTP_METHOD, http_url=None, 292 | parameters=None): 293 | if not parameters: 294 | parameters = {} 295 | 296 | parameters['oauth_token'] = token.key 297 | 298 | if callback: 299 | parameters['oauth_callback'] = callback 300 | 301 | return OAuthRequest(http_method, http_url, parameters) 302 | from_token_and_callback = staticmethod(from_token_and_callback) 303 | 304 | def _split_header(header): 305 | """Turn Authorization: header into parameters.""" 306 | params = {} 307 | parts = header.split(',') 308 | for param in parts: 309 | # Ignore realm parameter. 310 | if param.find('realm') > -1: 311 | continue 312 | # Remove whitespace. 313 | param = param.strip() 314 | # Split key-value. 315 | param_parts = param.split('=', 1) 316 | # Remove quotes and unescape the value. 317 | params[param_parts[0]] = urllib.parse.unquote(param_parts[1].strip('\"')) 318 | return params 319 | _split_header = staticmethod(_split_header) 320 | 321 | def _split_url_string(param_str): 322 | """Turn URL string into parameters.""" 323 | parameters = cgi.parse_qs(param_str, keep_blank_values=False) 324 | for k, v in parameters.items(): 325 | parameters[k] = urllib.parse.unquote(v[0]) 326 | return parameters 327 | _split_url_string = staticmethod(_split_url_string) 328 | 329 | 330 | class OAuthServer(object): 331 | """A worker to check the validity of a request against a data store.""" 332 | timestamp_threshold = 300 # In seconds, five minutes. 333 | version = VERSION 334 | signature_methods = None 335 | data_store = None 336 | 337 | def __init__(self, data_store=None, signature_methods=None): 338 | self.data_store = data_store 339 | self.signature_methods = signature_methods or {} 340 | 341 | def set_data_store(self, data_store): 342 | self.data_store = data_store 343 | 344 | def get_data_store(self): 345 | return self.data_store 346 | 347 | def add_signature_method(self, signature_method): 348 | self.signature_methods[signature_method.get_name()] = signature_method 349 | return self.signature_methods 350 | 351 | def fetch_request_token(self, oauth_request): 352 | """Processes a request_token request and returns the 353 | request token on success. 354 | """ 355 | try: 356 | # Get the request token for authorization. 357 | token = self._get_token(oauth_request, 'request') 358 | except OAuthError: 359 | # No token required for the initial token request. 360 | version = self._get_version(oauth_request) 361 | consumer = self._get_consumer(oauth_request) 362 | self._check_signature(oauth_request, consumer, None) 363 | # Fetch a new token. 364 | token = self.data_store.fetch_request_token(consumer) 365 | return token 366 | 367 | def fetch_access_token(self, oauth_request): 368 | """Processes an access_token request and returns the 369 | access token on success. 370 | """ 371 | version = self._get_version(oauth_request) 372 | consumer = self._get_consumer(oauth_request) 373 | # Get the request token. 374 | token = self._get_token(oauth_request, 'request') 375 | self._check_signature(oauth_request, consumer, token) 376 | new_token = self.data_store.fetch_access_token(consumer, token) 377 | return new_token 378 | 379 | def verify_request(self, oauth_request): 380 | """Verifies an api call and checks all the parameters.""" 381 | # -> consumer and token 382 | version = self._get_version(oauth_request) 383 | consumer = self._get_consumer(oauth_request) 384 | # Get the access token. 385 | token = self._get_token(oauth_request, 'access') 386 | self._check_signature(oauth_request, consumer, token) 387 | parameters = oauth_request.get_nonoauth_parameters() 388 | return consumer, token, parameters 389 | 390 | def authorize_token(self, token, user): 391 | """Authorize a request token.""" 392 | return self.data_store.authorize_request_token(token, user) 393 | 394 | def get_callback(self, oauth_request): 395 | """Get the callback URL.""" 396 | return oauth_request.get_parameter('oauth_callback') 397 | 398 | def build_authenticate_header(self, realm=''): 399 | """Optional support for the authenticate header.""" 400 | return {'WWW-Authenticate': 'OAuth realm="%s"' % realm} 401 | 402 | def _get_version(self, oauth_request): 403 | """Verify the correct version request for this server.""" 404 | try: 405 | version = oauth_request.get_parameter('oauth_version') 406 | except: 407 | version = VERSION 408 | if version and version != self.version: 409 | raise OAuthError('OAuth version %s not supported.' % str(version)) 410 | return version 411 | 412 | def _get_signature_method(self, oauth_request): 413 | """Figure out the signature with some defaults.""" 414 | try: 415 | signature_method = oauth_request.get_parameter( 416 | 'oauth_signature_method') 417 | except: 418 | signature_method = SIGNATURE_METHOD 419 | try: 420 | # Get the signature method object. 421 | signature_method = self.signature_methods[signature_method] 422 | except: 423 | signature_method_names = ', '.join(list(self.signature_methods.keys())) 424 | raise OAuthError('Signature method %s not supported try one of the' 425 | ' following: %s' % 426 | (signature_method, signature_method_names)) 427 | 428 | return signature_method 429 | 430 | def _get_consumer(self, oauth_request): 431 | consumer_key = oauth_request.get_parameter('oauth_consumer_key') 432 | consumer = self.data_store.lookup_consumer(consumer_key) 433 | if not consumer: 434 | raise OAuthError('Invalid consumer.') 435 | return consumer 436 | 437 | def _get_token(self, oauth_request, token_type='access'): 438 | """Try to find the token for the provided request token key.""" 439 | token_field = oauth_request.get_parameter('oauth_token') 440 | token = self.data_store.lookup_token(token_type, token_field) 441 | if not token: 442 | raise OAuthError('Invalid %s token: %s' % 443 | (token_type, token_field)) 444 | return token 445 | 446 | def _check_signature(self, oauth_request, consumer, token): 447 | timestamp, nonce = oauth_request._get_timestamp_nonce() 448 | self._check_timestamp(timestamp) 449 | self._check_nonce(consumer, token, nonce) 450 | signature_method = self._get_signature_method(oauth_request) 451 | try: 452 | signature = oauth_request.get_parameter('oauth_signature') 453 | except: 454 | raise OAuthError('Missing signature.') 455 | # Validate the signature. 456 | valid_sig = signature_method.check_signature(oauth_request, consumer, 457 | token, signature) 458 | if not valid_sig: 459 | key, base = signature_method.build_signature_base_string( 460 | oauth_request, consumer, token) 461 | raise OAuthError('Invalid signature. Expected signature base ' 462 | 'string: %s' % base) 463 | built = signature_method.build_signature(oauth_request, consumer, token) 464 | 465 | def _check_timestamp(self, timestamp): 466 | """Verify that timestamp is recentish.""" 467 | timestamp = int(timestamp) 468 | now = int(time.time()) 469 | lapsed = now - timestamp 470 | if lapsed > self.timestamp_threshold: 471 | raise OAuthError('Expired timestamp: given %d and now %s has a ' 472 | 'greater difference than threshold %d' % 473 | (timestamp, now, self.timestamp_threshold)) 474 | 475 | def _check_nonce(self, consumer, token, nonce): 476 | """Verify that the nonce is uniqueish.""" 477 | nonce = self.data_store.lookup_nonce(consumer, token, nonce) 478 | if nonce: 479 | raise OAuthError('Nonce already used: %s' % str(nonce)) 480 | 481 | 482 | class OAuthClient(object): 483 | """OAuthClient is a worker to attempt to execute a request.""" 484 | consumer = None 485 | token = None 486 | 487 | def __init__(self, oauth_consumer, oauth_token): 488 | self.consumer = oauth_consumer 489 | self.token = oauth_token 490 | 491 | def get_consumer(self): 492 | return self.consumer 493 | 494 | def get_token(self): 495 | return self.token 496 | 497 | def fetch_request_token(self, oauth_request): 498 | """-> OAuthToken.""" 499 | raise NotImplementedError 500 | 501 | def fetch_access_token(self, oauth_request): 502 | """-> OAuthToken.""" 503 | raise NotImplementedError 504 | 505 | def access_resource(self, oauth_request): 506 | """-> Some protected resource.""" 507 | raise NotImplementedError 508 | 509 | 510 | class OAuthDataStore(object): 511 | """A database abstraction used to lookup consumers and tokens.""" 512 | 513 | def lookup_consumer(self, key): 514 | """-> OAuthConsumer.""" 515 | raise NotImplementedError 516 | 517 | def lookup_token(self, oauth_consumer, token_type, token_token): 518 | """-> OAuthToken.""" 519 | raise NotImplementedError 520 | 521 | def lookup_nonce(self, oauth_consumer, oauth_token, nonce): 522 | """-> OAuthToken.""" 523 | raise NotImplementedError 524 | 525 | def fetch_request_token(self, oauth_consumer): 526 | """-> OAuthToken.""" 527 | raise NotImplementedError 528 | 529 | def fetch_access_token(self, oauth_consumer, oauth_token): 530 | """-> OAuthToken.""" 531 | raise NotImplementedError 532 | 533 | def authorize_request_token(self, oauth_token, user): 534 | """-> OAuthToken.""" 535 | raise NotImplementedError 536 | 537 | 538 | class OAuthSignatureMethod(object): 539 | """A strategy class that implements a signature method.""" 540 | def get_name(self): 541 | """-> str.""" 542 | raise NotImplementedError 543 | 544 | def build_signature_base_string(self, oauth_request, 545 | oauth_consumer, oauth_token): 546 | """-> str key, str raw.""" 547 | raise NotImplementedError 548 | 549 | def build_signature(self, oauth_request, oauth_consumer, oauth_token): 550 | """-> str.""" 551 | raise NotImplementedError 552 | 553 | def check_signature(self, oauth_request, consumer, token, signature): 554 | built = self.build_signature(oauth_request, consumer, token) 555 | return built == signature 556 | 557 | 558 | class OAuthSignatureMethod_HMAC_SHA1(OAuthSignatureMethod): 559 | 560 | def get_name(self): 561 | return 'HMAC-SHA1' 562 | 563 | def build_signature_base_string(self, oauth_request, consumer, token): 564 | sig = ( 565 | escape(oauth_request.get_normalized_http_method()), 566 | escape(oauth_request.get_normalized_http_url()), 567 | escape(oauth_request.get_normalized_parameters()), 568 | ) 569 | 570 | key = '%s&' % escape(consumer.secret) 571 | if token and token.secret: 572 | key += escape(token.secret) 573 | raw = '&'.join(sig) 574 | return key, raw 575 | 576 | def build_signature(self, oauth_request, consumer, token): 577 | """Builds the base signature string.""" 578 | key, raw = self.build_signature_base_string(oauth_request, consumer, 579 | token) 580 | 581 | # Compute the oauth hmac Python 3.0 style 582 | # http://stackoverflow.com/questions/1306550/calculating-a-sha-hash-with-a-string-secret-key-in-python 583 | import hashlib 584 | import base64 585 | import hmac 586 | hashed = hmac.new(bytearray(key, 'latin1'), 587 | bytearray(raw, 'latin1'), hashlib.sha1) 588 | 589 | # Calculate the digest base 64. 590 | digest = hashed.digest() 591 | enc = base64.b64encode(digest).decode() # py3k-mode 592 | return enc 593 | 594 | 595 | class OAuthSignatureMethod_PLAINTEXT(OAuthSignatureMethod): 596 | 597 | def get_name(self): 598 | return 'PLAINTEXT' 599 | 600 | def build_signature_base_string(self, oauth_request, consumer, token): 601 | """Concatenates the consumer key and secret.""" 602 | sig = '%s&' % escape(consumer.secret) 603 | if token: 604 | sig = sig + escape(token.secret) 605 | return sig, sig 606 | 607 | def build_signature(self, oauth_request, consumer, token): 608 | key, raw = self.build_signature_base_string(oauth_request, consumer, 609 | token) 610 | return key -------------------------------------------------------------------------------- /parser.py: -------------------------------------------------------------------------------- 1 | # To run this, download the BeautifulSoup zip file 2 | # http://www.py4e.com/code3/bs4.zip 3 | # and unzip it in the same directory as this file 4 | 5 | import urllib.request, urllib.parse, urllib.error 6 | from bs4 import BeautifulSoup 7 | import ssl 8 | 9 | # Ignore SSL certificate errors 10 | ctx = ssl.create_default_context() 11 | ctx.check_hostname = False 12 | ctx.verify_mode = ssl.CERT_NONE 13 | 14 | url = input('Enter - ') 15 | html = urllib.request.urlopen(url, context=ctx).read() 16 | soup = BeautifulSoup(html, 'html.parser') 17 | 18 | # Retrieve all of the anchor tags 19 | tags = soup('a') 20 | for tag in tags: 21 | # Look at the parts of a tag 22 | print('TAG:', tag) 23 | print('URL:', tag.get('href', None)) 24 | print('Contents:', tag.contents[0]) 25 | print('Attrs:', tag.attrs) -------------------------------------------------------------------------------- /pi_estimate.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | tries = 10000 4 | in_count = 0 5 | out_count = 0 6 | for i in range(1, tries): 7 | x = random.uniform(0, 1) 8 | y = random.uniform(0, 1) 9 | g = random.uniform(0, 1) 10 | ss = 's' 11 | 12 | c = x ** 2 + y ** 2 13 | 14 | if c <= 1: 15 | in_count += 1 16 | else: 17 | out_count += 1 18 | 19 | print('pi is around ~', 4 * in_count / (out_count + in_count)) 20 | -------------------------------------------------------------------------------- /regex.py: -------------------------------------------------------------------------------- 1 | import re 2 | import timeit 3 | 4 | pattern = str(input('Enter regexp pattern you want to search for: ')) 5 | 6 | 7 | def testing_speed(): 8 | count = 0 9 | sum = 0 10 | with open('mbox.txt', 'r', encoding='utf-8') as file: 11 | for line in file: 12 | if re.findall(pattern, line): 13 | sum += int(re.findall(pattern, line)[0]) 14 | count += 1 15 | print(f'Found {count} match(es), avg = {sum/count}') 16 | 17 | 18 | elapsed_time = timeit.timeit(testing_speed, number=1) 19 | print(elapsed_time) 20 | 21 | 22 | -------------------------------------------------------------------------------- /rhyming_master.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import webbrowser 3 | 4 | def get_rhymes(word): 5 | baseurl = "https://api.datamuse.com/words" 6 | params_diction = \ 7 | { 8 | "rel_rhy": word, 9 | "max": "3" 10 | } 11 | resp = requests.get(baseurl, params=params_diction) 12 | # return the top three words 13 | word_ds = resp.json() 14 | return [d['word'] for d in word_ds] 15 | # return resp.json() # Return a python object (a list of dictionaries in this case) 16 | 17 | 18 | parag = '''The answers to questions two and three, about the contents of the 19 | value of the params dictionary, can be found in the section of the 20 | documentation that describes the particular endpoint. For example, take a 21 | look at the documentation for the “words” endpoint. The entire request will 22 | return some words, and all of the params contents will specify constraints 23 | that restrict the search. ''' 24 | 25 | webbrowser.open('www.google.com') -------------------------------------------------------------------------------- /server.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import requests 3 | import re 4 | my_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 5 | url = str(input()) 6 | 7 | my_socket.connect((url.split('/')[2], 80)) 8 | 9 | cmd = f'GET {url} HTTP/1.0\n\n'.encode() 10 | 11 | my_socket.send(cmd) 12 | file = [] 13 | while True: 14 | data = my_socket.recv(512) 15 | data = data.decode().split('\n') 16 | if data.count('Content-Length'): 17 | file.append(data) 18 | if not data: 19 | break 20 | 21 | print(file[0]) 22 | my_socket.close() 23 | 24 | # url = 'http://data.pr4e.org/intro-short.txt' 25 | # resp = requests.get(url) 26 | # 27 | # print(resp.headers['Last-Modified']) 28 | # print(resp.headers['ETag']) 29 | # print(resp.headers['Content-Length']) 30 | # print(resp.headers['Cache-Control']) 31 | # print(resp.headers['Content-Type']) -------------------------------------------------------------------------------- /soup1.py: -------------------------------------------------------------------------------- 1 | import urllib.request, urllib.parse, urllib.error 2 | from bs4 import BeautifulSoup 3 | import ssl 4 | 5 | # Ignore SSL certificate errors 6 | ctx = ssl.create_default_context() 7 | ctx.check_hostname = False 8 | ctx.verify_mode = ssl.CERT_NONE 9 | 10 | url = input('Enter - ') 11 | html = urllib.request.urlopen(url, context=ctx).read() 12 | soup = BeautifulSoup(html, 'html.parser') 13 | 14 | # Retrieve all of the anchor tags 15 | tags = soup('span') 16 | sum = 0 17 | for tag in tags: 18 | # Look at the parts of a tag 19 | sum += int(tag.contents[0]) 20 | 21 | print(sum) -------------------------------------------------------------------------------- /soup2.py: -------------------------------------------------------------------------------- 1 | # To run this, download the BeautifulSoup zip file 2 | # http://www.py4e.com/code3/bs4.zip 3 | # and unzip it in the same directory as this file 4 | 5 | import urllib.request, urllib.parse, urllib.error 6 | from bs4 import BeautifulSoup 7 | import ssl 8 | 9 | # Ignore SSL certificate errors 10 | ctx = ssl.create_default_context() 11 | ctx.check_hostname = False 12 | ctx.verify_mode = ssl.CERT_NONE 13 | 14 | url = str(input('enter url: ')) 15 | count = int(input('enter count: ')) 16 | pos = int(input('enter position: ')) 17 | 18 | # Retrieve all of the anchor tags 19 | for _ in range(count): 20 | html = urllib.request.urlopen(url, context=ctx).read() 21 | soup = BeautifulSoup(html, 'html.parser') 22 | array = [] 23 | tags = soup('a') 24 | for tag in tags: 25 | array.append(tag.get('href', None)) 26 | url = array[pos-1] 27 | 28 | 29 | print(array[pos-1].split('/')[3].split('_')[2].split('.')[0]) -------------------------------------------------------------------------------- /test_download.py: -------------------------------------------------------------------------------- 1 | import urllib.request, urllib.parse, urllib.error 2 | import datetime 3 | 4 | date = datetime.date.today() 5 | url = str(input("enter url to download: ")) 6 | 7 | img = urllib.request.urlopen(url) 8 | fhand = open(f'{date}-TV.epub', 'wb') 9 | size = 0 10 | while True: 11 | info = img.read(100000) 12 | if not info: 13 | break 14 | size = size + len(info) 15 | fhand.write(info) 16 | 17 | print(size, 'characters copied.') 18 | fhand.close() 19 | -------------------------------------------------------------------------------- /tuples.py: -------------------------------------------------------------------------------- 1 | name = "data.txt" 2 | 3 | # sorted hourly track 4 | count = {} 5 | with open('data.txt', 'r', encoding='utf-8') as file: 6 | 7 | for line in file.readlines(): 8 | if line.count('2008') == 1 and line.count('From'): 9 | hour = line.split(':')[0].split()[-1] 10 | 11 | if hour in count.keys(): 12 | count[hour] += 1 13 | elif hour not in count.keys(): 14 | count[hour] = 1 15 | 16 | for k, v in sorted(count.items()): 17 | print(k, v) 18 | 19 | # most messages 20 | # with open('data.txt', 'r', encoding='utf-8') as file: 21 | # 22 | # for line in file.readlines(): 23 | # if line.count('2008') == 1 and line.count('From'): 24 | # sender = line.split()[1] 25 | # 26 | # if sender in count.keys(): 27 | # count[sender] += 1 28 | # elif sender not in count.keys(): 29 | # count[sender] = 1 30 | # 31 | # maxim = 0 32 | # for k, v in sorted(count.items()): 33 | # tmp = v 34 | # if maxim < tmp: 35 | # maxim, user = v, k 36 | # 37 | # print(user, maxim) 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /tuples1.py: -------------------------------------------------------------------------------- 1 | import timeit 2 | 3 | def stupid(): 4 | name = "data.txt" 5 | count = 0 6 | sample = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM' 7 | with open('data.txt', 'r', encoding='utf-8') as file: 8 | 9 | for line in file.readlines(): 10 | line = line.lower() 11 | for char in line: 12 | if char in sample: 13 | count += 1 14 | 15 | 16 | def code_to_test(): 17 | name = "data.txt" 18 | count = {} 19 | total = 0 20 | sample = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM' 21 | with open('data.txt', 'r', encoding='utf-8') as file: 22 | 23 | for line in file.readlines(): 24 | line = line.lower() 25 | for char in line: 26 | if char in sample: 27 | total += 1 28 | if char in count.keys(): 29 | count[char] += 1 30 | elif char not in count.keys(): 31 | count[char] = 1 32 | 33 | maximum = 0 34 | for k, v in sorted(count.items()): 35 | tmp = v 36 | if maximum < tmp: 37 | maximum, user = v, k 38 | 39 | for k, v in sorted(count.items()): 40 | return(k, v, 'percentage = ', round(v / total * 100, 3), '%') 41 | 42 | print('max used = ', user, maximum) 43 | 44 | 45 | elapsed_time = timeit.timeit(code_to_test, number=10) / 10 46 | print(elapsed_time) 47 | 48 | 49 | -------------------------------------------------------------------------------- /twitter.py: -------------------------------------------------------------------------------- 1 | import urllib.request, urllib.parse, urllib.error 2 | import twurl 3 | import ssl 4 | 5 | # https://apps.twitter.com/ 6 | # Create App and get the four strings, put them in hidden.py 7 | 8 | TWITTER_URL = 'https://api.twitter.com/1.1/statuses/user_timeline.json' 9 | 10 | # Ignore SSL certificate errors 11 | ctx = ssl.create_default_context() 12 | ctx.check_hostname = False 13 | ctx.verify_mode = ssl.CERT_NONE 14 | 15 | while True: 16 | print('') 17 | acct = input('Enter Twitter Account:') 18 | if (len(acct) < 1): break 19 | url = twurl.augment(TWITTER_URL, 20 | {'screen_name': acct, 'count': '2'}) 21 | print('Retrieving', url) 22 | connection = urllib.request.urlopen(url, context=ctx) 23 | data = connection.read().decode() 24 | print(data[:250]) 25 | headers = dict(connection.getheaders()) 26 | # print headers 27 | print('Remaining', headers['x-rate-limit-remaining']) -------------------------------------------------------------------------------- /twurl.py: -------------------------------------------------------------------------------- 1 | import urllib.request, urllib.parse, urllib.error 2 | import oauth 3 | import hidden 4 | 5 | # https://apps.twitter.com/ 6 | # Create App and get the four strings, put them in hidden.py 7 | 8 | def augment(url, parameters): 9 | secrets = hidden.oauth() 10 | consumer = oauth.OAuthConsumer(secrets['consumer_key'], 11 | secrets['consumer_secret']) 12 | token = oauth.OAuthToken(secrets['token_key'], secrets['token_secret']) 13 | 14 | oauth_request = oauth.OAuthRequest.from_consumer_and_token(consumer, 15 | token=token, http_method='GET', http_url=url, 16 | parameters=parameters) 17 | oauth_request.sign_request(oauth.OAuthSignatureMethod_HMAC_SHA1(), 18 | consumer, token) 19 | return oauth_request.to_url() 20 | 21 | 22 | def test_me(): 23 | print('* Calling Twitter...') 24 | url = augment('https://api.twitter.com/1.1/statuses/user_timeline.json', 25 | {'screen_name': 'drchuck', 'count': '2'}) 26 | print(url) 27 | connection = urllib.request.urlopen(url) 28 | data = connection.read() 29 | print(data) 30 | headers = dict(connection.getheaders()) 31 | print(headers) -------------------------------------------------------------------------------- /wheel_game.py: -------------------------------------------------------------------------------- 1 | import json 2 | import random 3 | import time 4 | 5 | VOWEL_COST = 250 6 | LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 7 | VOWELS = 'AEIOU' 8 | SORTED_FREQUENCIES = 'ZQXJKVBPYGFWMUCLDRHSNIOATE' 9 | 10 | 11 | # Write the WOFPlayer class definition (part A) here 12 | class WOFPlayer: 13 | def __init__(self, name): 14 | self.name = name 15 | self.prizeMoney = 0 16 | self.prizes = [] 17 | 18 | def addMoney(self, amt): 19 | self.prizeMoney += amt 20 | 21 | def goBankrupt(self): 22 | self.prizeMoney = 0 23 | 24 | def addPrize(self, prize): 25 | self.prizes.append(prize) 26 | 27 | def __str__(self): 28 | return '{} (${})'.format(self.name, self.prizeMoney) 29 | 30 | 31 | # Write the WOFHumanPlayer class definition (part B) here 32 | 33 | class WOFHumanPlayer(WOFPlayer): 34 | def __init__(self, name): 35 | super().__init__(name) 36 | 37 | def getMove(self, category, obscuredPhrase, guessed): 38 | print('{} has ${}'.format(self.name, self.prizeMoney)) 39 | print('\n') 40 | print('Category: {}'.format(category)) 41 | print('Phrase: {}'.format(obscuredPhrase)) 42 | print('Guessed: {}'.format(guessed)) 43 | print('\n') 44 | inpt = str(input('Guess a letter, phrase, or type "exit" or "pass":')) 45 | return inpt 46 | 47 | 48 | # Write the WOFComputerPlayer class definition (part C) here 49 | class WOFComputerPlayer(WOFPlayer): 50 | SORTED_FREQUENCIES = 'ZQXJKVBPYGFWMUCLDRHSNIOATE' 51 | 52 | def __init__(self, name, difficulty): 53 | super().__init__(name) 54 | self.difficulty = difficulty 55 | 56 | def smartCoinFlip(self): 57 | return random.randint(1, 10) <= self.difficulty 58 | 59 | def getPossibleLetters(self, guessed): 60 | can_be = [] 61 | for letter in LETTERS: 62 | if letter not in guessed: 63 | can_be.append(letter) 64 | 65 | if self.prizeMoney > VOWEL_COST: 66 | return can_be 67 | 68 | else: 69 | new = [] 70 | for l in can_be: 71 | if (l not in VOWELS): 72 | new.append(l) 73 | return new 74 | 75 | def getMove(self, category, obscuredPhrase, guessed): 76 | print('{} has ${}'.format(self.name, self.prizeMoney)) 77 | print('\n') 78 | print('Category: {}'.format(category)) 79 | print('Phrase: {}'.format(obscuredPhrase)) 80 | print('Guessed: {}'.format(guessed)) 81 | print('\n') 82 | 83 | possible = self.getPossibleLetters(guessed) 84 | if possible: 85 | if self.smartCoinFlip(): 86 | max_index = 0 87 | for letter in possible: 88 | if SORTED_FREQUENCIES.index(letter) >= max_index: 89 | max_index = SORTED_FREQUENCIES.index(letter) 90 | return SORTED_FREQUENCIES[max_index] 91 | else: 92 | return random.choice(possible) 93 | else: 94 | return 'pass' 95 | 96 | 97 | # PASTE YOUR WOFPlayer CLASS (from part A) HERE 98 | # PASTE YOUR WOFHumanPlayer CLASS (from part B) HERE 99 | # PASTE YOUR WOFComputerPlayer CLASS (from part C) HERE 100 | 101 | 102 | # Repeatedly asks the user for a number between min & max (inclusive) 103 | def getNumberBetween(prompt, min, max): 104 | userinp = input(prompt) # ask the first time 105 | 106 | while True: 107 | try: 108 | n = int(userinp) # try casting to an integer 109 | if n < min: 110 | errmessage = 'Must be at least {}'.format(min) 111 | elif n > max: 112 | errmessage = 'Must be at most {}'.format(max) 113 | else: 114 | return n 115 | except ValueError: # The user didn't enter a number 116 | errmessage = '{} is not a number.'.format(userinp) 117 | 118 | # If we haven't gotten a number yet, add the error message 119 | # and ask again 120 | userinp = input('{}\n{}'.format(errmessage, prompt)) 121 | 122 | 123 | # Spins the wheel of fortune wheel to give a random prize Examples: { 124 | # "type": "cash", "text": "$950", "value": 950, "prize": "A trip to Ann 125 | # Arbor!" }, { "type": "bankrupt", "text": "Bankrupt", "prize": false }, 126 | # { "type": "loseturn", "text": "Lose a turn", "prize": false } 127 | def spinWheel(): 128 | with open("wheel.json", 'r') as f: 129 | wheel = json.loads(f.read()) 130 | return random.choice(wheel) 131 | 132 | 133 | # Returns a category & phrase (as a tuple) to guess 134 | # Example: 135 | # ("Artist & Song", "Whitney Houston's I Will Always Love You") 136 | def getRandomCategoryAndPhrase(): 137 | with open("phrases.json", 'r') as f: 138 | phrases = json.loads(f.read()) 139 | 140 | category = random.choice(list(phrases.keys())) 141 | phrase = random.choice(phrases[category]) 142 | return (category, phrase.upper()) 143 | 144 | 145 | # Given a phrase and a list of guessed letters, returns an obscured version 146 | # Example: 147 | # guessed: ['L', 'B', 'E', 'R', 'N', 'P', 'K', 'X', 'Z'] 148 | # phrase: "GLACIER NATIONAL PARK" 149 | # returns> "_L___ER N____N_L P_RK" 150 | def obscurePhrase(phrase, guessed): 151 | rv = '' 152 | for s in phrase: 153 | if (s in LETTERS) and (s not in guessed): 154 | rv = rv + '_' 155 | else: 156 | rv = rv + s 157 | return rv 158 | 159 | 160 | # Returns a string representing the current state of the game 161 | def showBoard(category, obscuredPhrase, guessed): 162 | return """ 163 | Category: {} 164 | Phrase: {} 165 | Guessed: {}""".format(category, obscuredPhrase, ', '.join(sorted(guessed))) 166 | 167 | 168 | # GAME LOGIC CODE 169 | print('=' * 15) 170 | print('WHEEL OF PYTHON') 171 | print('=' * 15) 172 | print('') 173 | 174 | num_human = getNumberBetween('How many human players?', 0, 10) 175 | 176 | # Create the human player instances 177 | human_players = [ 178 | WOFHumanPlayer(input('Enter the name for human player #{}'.format(i + 1))) 179 | for i in range(num_human)] 180 | 181 | num_computer = getNumberBetween('How many computer players?', 0, 10) 182 | 183 | # If there are computer players, ask how difficult they should be 184 | if num_computer >= 1: 185 | difficulty = getNumberBetween('What difficulty for the computers? (1-10)', 186 | 1, 10) 187 | 188 | # Create the computer player instances 189 | computer_players = [WOFComputerPlayer('Computer {}'.format(i + 1), difficulty) 190 | for i in range(num_computer)] 191 | 192 | players = human_players + computer_players 193 | 194 | # No players, no game :( 195 | if len(players) == 0: 196 | print('We need players to play!') 197 | raise Exception('Not enough players') 198 | 199 | # category and phrase are strings. 200 | category, phrase = getRandomCategoryAndPhrase() 201 | # guessed is a list of the letters that have been guessed 202 | guessed = [] 203 | 204 | # playerIndex keeps track of the index (0 to len(players)-1) of the player 205 | # whose turn it is 206 | playerIndex = 0 207 | 208 | # will be set to the player instance when/if someone wins 209 | winner = False 210 | 211 | 212 | def requestPlayerMove(player, category, guessed): 213 | while True: # we're going to keep asking the player for a move until 214 | # they give a valid one 215 | time.sleep(0.1) 216 | # added so that any feedback is printed out before the 217 | # next prompt 218 | 219 | move = player.getMove(category, obscurePhrase(phrase, guessed), 220 | guessed) 221 | move = move.upper() # convert whatever the player entered to UPPERCASE 222 | if move == 'EXIT' or move == 'PASS': 223 | return move 224 | elif len(move) == 1: # they guessed a character 225 | if move not in LETTERS: # the user entered an invalid letter ( 226 | # such as @, #, or $) 227 | print('Guesses should be letters. Try again.') 228 | continue 229 | elif move in guessed: # this letter has already been guessed 230 | print('{} has already been guessed. Try again.'.format(move)) 231 | break 232 | elif move in VOWELS and player.prizeMoney < VOWEL_COST: # if 233 | # it's a vowel, we need to be sure the player has enough 234 | print( 235 | 'Need ${} to guess a vowel. Try again.'.format(VOWEL_COST)) 236 | continue 237 | else: 238 | return move 239 | else: # they guessed the phrase 240 | return move 241 | 242 | 243 | while True: 244 | player = players[playerIndex] 245 | wheelPrize = spinWheel() 246 | 247 | print('') 248 | print('-' * 15) 249 | print(showBoard(category, obscurePhrase(phrase, guessed), guessed)) 250 | print('') 251 | print('{} spins...'.format(player.name)) 252 | time.sleep(2) # pause for dramatic effect! 253 | print('{}!'.format(wheelPrize['text'])) 254 | time.sleep(1) # pause again for more dramatic effect! 255 | 256 | if wheelPrize['type'] == 'bankrupt': 257 | player.goBankrupt() 258 | continue 259 | elif wheelPrize['type'] == 'loseturn': 260 | pass # do nothing; just move on to the next player 261 | elif wheelPrize['type'] == 'cash': 262 | move = requestPlayerMove(player, category, guessed) 263 | if move == 'EXIT': # leave the game 264 | print('Until next time!') 265 | break 266 | elif move == 'PASS': # will just move on to next player 267 | print('{} passes'.format(player.name)) 268 | elif move: # they guessed a letter 269 | guessed.append(move) 270 | 271 | print('{} guesses "{}"'.format(player.name, move)) 272 | 273 | if move in VOWELS: 274 | player.prizeMoney -= VOWEL_COST 275 | 276 | count = phrase.count( 277 | move) # returns an integer with how many times this letter appears 278 | if count: 279 | if count == 1: 280 | print("There is one {}".format(move)) 281 | else: 282 | print("There are {} {}'s".format(count, move)) 283 | 284 | # Give them the money and the prizes 285 | player.addMoney(count * wheelPrize['value']) 286 | if wheelPrize['prize']: 287 | player.addPrize(wheelPrize['prize']) 288 | 289 | # all of the letters have been guessed 290 | if obscurePhrase(phrase, guessed) == phrase: 291 | winner = player 292 | break 293 | 294 | continue # this player gets to go again 295 | 296 | elif count == 0: 297 | print("There is no {}".format(move)) 298 | else: # they guessed the whole phrase 299 | if move == phrase: # they guessed the full phrase correctly 300 | winner = player 301 | 302 | # Give them the money and the prizes 303 | player.addMoney(wheelPrize['value']) 304 | if wheelPrize['prize']: 305 | player.addPrize(wheelPrize['prize']) 306 | 307 | break 308 | else: 309 | print('{} was not the phrase'.format(move)) 310 | 311 | # Move on to the next player (or go back to player[0] if the end) 312 | playerIndex = (playerIndex + 1) % len(players) 313 | 314 | if winner: 315 | # In your head, you should hear this as being announced by a game show host 316 | print('{} wins! The phrase was {}'.format(winner.name, phrase)) 317 | print('{} won ${}'.format(winner.name, winner.prizeMoney)) 318 | if len(winner.prizes) > 0: 319 | print('{} also won:'.format(winner.name)) 320 | for prize in winner.prizes: 321 | print(' - {}'.format(prize)) 322 | else: 323 | print('Nobody won. The phrase was {}'.format(phrase)) 324 | -------------------------------------------------------------------------------- /xml_samples.py: -------------------------------------------------------------------------------- 1 | import urllib.request, urllib.parse, urllib.error 2 | import xml.etree.ElementTree as ET 3 | import ssl 4 | 5 | 6 | # Ignore SSL certificate errors 7 | ctx = ssl.create_default_context() 8 | ctx.check_hostname = False 9 | ctx.verify_mode = ssl.CERT_NONE 10 | 11 | 12 | url = 'https://py4e-data.dr-chuck.net/comments_1245984.xml' 13 | 14 | data = urllib.request.urlopen(url, context=ctx).read().decode() 15 | tree = ET.fromstring(data) 16 | sum = 0 17 | 18 | counts = tree.findall('comments/comment') 19 | 20 | for comment in counts: 21 | sum += int(comment.find('count').text) 22 | 23 | print(sum) --------------------------------------------------------------------------------