├── 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)
--------------------------------------------------------------------------------