I'm currently practicing on recursion and growing lists. However, I encountered an error where both "AND" and "NOT IN" functions won't work. It keeps on returning True regardless of the outcome.
Based on the code, this line:
if (a not in routeList) and (b not in routeList):
won't work.
Here's my Input and Output:
You are currently in LGA airport.
Here are the airports
['BIG', 'CDG', 'GGG', 'DEL', 'DOH', 'DSM', 'EWR', 'EYW', 'HND', 'ICN', 'JFK', 'LGA', 'LHR', 'ORD', 'SAN', 'SFO', 'SIN', 'TLV', 'BUD']
-What's your destination? SIN
count: 0
a CDG
routeList [['CDG']]
count: 1
a FFF
routeList [['CDG'], ['FFF']]
count: 2
b CDG
routeList [['CDG'], ['FFF'], ['CDG']]
The last array ['CDG'] should not be included on the current routeList because it already exists. How can I fix this?
#You must return the shortest path in any airports.
#The starting Airport should be in LGA
#List of Airports
airports = ['BIG', 'CDG', 'GGG', 'DEL', 'DOH', 'DSM', 'EWR', 'EYW', 'HND', 'ICN', 'JFK', 'LGA', 'LHR', 'ORD', 'SAN', 'SFO', 'SIN', 'TLV', 'BUD']
#This is the airport routes
routes = [
['BGI', 'LGA'],
['CDG', 'BUD'],
['CDG', 'SIN'],
['DEL', 'CDG'],
['DEL', 'DOH'],
['DSM', 'ORD'],
['EWR', 'HND'],
['EYW', 'LHR'],
['FFF', 'SIN'],
['HND', 'ICN'],
['HND', 'JFK'],
['ICN', 'JFK'],
['JFK', 'LGA'],
['LHR', 'SFO'],
['ORD', 'BGI'],
['SAN', 'EYW'],
['SFO', 'DSM'],
['SFO', 'SAN'],
['SIN', 'CDG'],
['TLV', 'DEL'],
]
startingAirport = 'LGA'
routeList = []
tempList = []
def checkRoute(startPt):
global routes
global routeList
global startingAirport
tempList = []
count1 = 0
for i in routes:
if startPt in i:
a,b = i
if (a not in routeList) and (b not in routeList):# == True:
#if (a,b) not in routeList:
print('count: %d' %count1)
if (a != startPt):# and (a not in routeList):
tempList.append(a)
print('a', a)
elif b != startPt:# and (b not in routeList):
tempList.append(b)
print('b', b)
count1+=1
routeList.append(tempList[:])
print('routeList',routeList)
tempList.clear()
def main():
print(len(routes))
print("You are currently in %s airport.\n" % startingAirport)
print("Here are the airports")
print(airports)
userIn = input("What's your destination? ")
if userIn not in airports:
print("\nThis Airport name is not listed. Please try again")
main()
else:
checkRoute(userIn)
main()
Your problem is that the string 'CDG' does not equal the array ['CDG']
It's a little messy but I trust you can clean it up:
if ([a] not in routeList) and ([b] not in routeList):
count1+=1
print('count: %d' %count1)
if (a != startPt):
tempList.append(a)
print('a', a)
elif b != startPt:
tempList.append(b)
print('b', b)
routeList.append(tempList[:])
print('routeList',routeList)
tempList.clear()
Related
I have the following function which produces results;
myNames = ['ULTA', 'CSCO', ...]
def get_from_min_match(var):
temp = []
count_elem = generate_elem_count()
for item in count_elem:
if var <= count_elem[item]:
temp.append(item)
return set(temp) if len(set(temp)) > 0 else "None"
def generate_elem_count():
result_data = []
for val in mapper.values():
if type(val) == list:
result_data += val
elif type(val) == dict:
for key in val:
result_data.append(key)
count_elem = {elem: result_data.count(elem) for elem in result_data}
return count_elem
I call this function like this;
myNames_dict_1 = ['AME', 'IEX', 'PAYC']
myNames_dict_1 = ['ULTA', 'CSCO', 'PAYC']
mapper = {1: myNames_dict_1, 2: myNames_dict_2}
print(" These meet three values ", get_from_min_match(3))
print(" These meet four values ", get_from_min_match(4))
The output I get from these functions are as follows;
These meet three values {'ULTA', 'CSCO', 'SHW', 'MANH', 'TTWO', 'SAM', 'RHI', 'PAYC', 'AME', 'CCOI', 'RMD', 'AMD', 'UNH', 'AZO', 'APH', 'EW', 'FFIV', 'IEX', 'IDXX', 'ANET', 'SWKS', 'HRL', 'ILMN', 'PGR', 'ATVI', 'CNS', 'EA', 'ORLY', 'TSCO'}
These meet four values {'EW', 'PAYC', 'TTWO', 'AME', 'IEX', 'IDXX', 'ANET', 'RMD', 'SWKS', 'HRL', 'UNH', 'CCOI', 'ORLY', 'APH', 'PGR', 'TSCO'}
Now, I want to insert the output, of the get_from_min_match function into a Sqlite database. Its structure looks like this;
dbase.execute("INSERT OR REPLACE INTO min_match (DATE, SYMBOL, NAME, NUMBEROFMETRICSMET) \
VALUES (?,?,?,?)", (datetime.today(), symbol, name, NUMBEROFMETRICSMET?))
dbase.commit()
So, it's basically a new function to calculate the "NUMBEROFMETRICSMET" parameter rather than calling each of these functions many times. And I want the output of the function inserted into the database. How to achieve this? Here 3, 4 would be the number of times the companies matched.
date ULTA name 3
date EW name 4
...
should be the result.
How can I achieve this? Thanks!
I fixed this by just using my already written function;
count_elem = generate_elem_count()
print("Count Elem: " + str(count_elem))
This prints {'AMPY': 1} and so on.
I am making a seating app in Python which takes a list of 10 names and gives every student a seat. The seats are 2 row of 5 seats.
I wrote a simple script to do that, but I am stuck at looping the seats for the students. Here is my code:
from pprint import pprint as pp
C = "ABCDE"
R = range(0, 2)
students= ["rob", "tim", "kaleb", "josh", "victoria", "amy", "fred", "xander", "cody", "dump man"]
seats = [{str(y)+ltr:"EMPTY" for ltr in C} for y in R]
for names in range(10):
for i in range(2):
for letters in C:
for s in range(1):
print(f'{i}{letters}')
seats[i][f"{i}{letters}"]=students[names]
pp(seats)
As you can see, at the loop I am iterating over the letters and numbers of SEATS. However, when coming to iterate of students names, it always gives me 10. Can you please help!
This should work:
C = "ABCDE"
number_of_rows = 2
R = range(number_of_rows)
seats_per_row = 5
students= ["rob", "tim", "kaleb", "josh", "victoria", "amy", "fred", "xander", "cody", "dump man"]
seats = [{str(y)+ltr:"EMPTY" for ltr in C} for y in R]
for row in range(number_of_rows):
for seat in range(seats_per_row):
letter = C[seat]
name = students[row * seats_per_row + seat]
seats[row][f"{row}{letter}"]=name
print(seats)
OUTPUT:
[{'0A': 'rob', '0B': 'tim', '0C': 'kaleb', '0D': 'josh', '0E': 'victoria'}, {'1A': 'amy', '1B': 'fred', '1C': 'xander', '1D': 'cody', '1E': 'dump man'}]
I want to find stand-alone or successively connected nouns in a text. I put together below code, but it is neither efficient nor pythonic. Does anybody have a more pythonic way of finding these nouns with spaCy?
Below code builds a dict with all tokens and then runs through them to find stand-alone or connected PROPN or NOUN until the for-loop runs out of range. It returns a list of the collected items.
def extract_unnamed_ents(doc):
"""Takes a string and returns a list of all succesively connected nouns or pronouns"""
nlp_doc = nlp(doc)
token_list = []
for token in nlp_doc:
token_dict = {}
token_dict['lemma'] = token.lemma_
token_dict['pos'] = token.pos_
token_dict['tag'] = token.tag_
token_list.append(token_dict)
ents = []
k = 0
for i in range(len(token_list)):
try:
if token_list[k]['pos'] == 'PROPN' or token_list[k]['pos'] == 'NOUN':
ent = token_list[k]['lemma']
if token_list[k+1]['pos'] == 'PROPN' or token_list[k+1]['pos'] == 'NOUN':
ent = ent + ' ' + token_list[k+1]['lemma']
k += 1
if token_list[k+1]['pos'] == 'PROPN' or token_list[k+1]['pos'] == 'NOUN':
ent = ent + ' ' + token_list[k+1]['lemma']
k += 1
if token_list[k+1]['pos'] == 'PROPN' or token_list[k+1]['pos'] == 'NOUN':
ent = ent + ' ' + token_list[k+1]['lemma']
k += 1
if token_list[k+1]['pos'] == 'PROPN' or token_list[k+1]['pos'] == 'NOUN':
ent = ent + ' ' + token_list[k+1]['lemma']
k += 1
if ent not in ents:
ents.append(ent)
except:
pass
k += 1
return ents
Test:
extract_unnamed_ents('Chancellor Angela Merkel and some of her ministers will discuss at a cabinet '
"retreat next week ways to avert driving bans in major cities after Germany's "
'top administrative court in February allowed local authorities to bar '
'heavily polluting diesel cars.')
Out:
['Chancellor Angela Merkel',
'minister',
'cabinet retreat',
'week way',
'ban',
'city',
'Germany',
'court',
'February',
'authority',
'diesel car']
spacy has a way of doing this but I'm not sure it is giving you exactly what you are after
import spacy
text = """Chancellor Angela Merkel and some of her ministers will discuss
at a cabinet retreat next week ways to avert driving bans in
major cities after Germany's top administrative court
in February allowed local authorities to bar heavily
polluting diesel cars.
""".replace('\n', ' ')
nlp = spacy.load("en_core_web_sm")
doc = nlp(text)
print([i.text for i in doc.noun_chunks])
gives
['Chancellor Angela Merkel', 'her ministers', 'a cabinet retreat', 'ways', 'driving bans', 'major cities', "Germany's top administrative court", 'February', 'local authorities', 'heavily polluting diesel cars']
Here, however the i.lemma_ line doesn't really give you what you want (I think this might be fixed by this recent PR).
Since it isn't quite what you are after you could use itertools.groupby like so
import itertools
out = []
for i, j in itertools.groupby(doc, key=lambda i: i.pos_):
if i not in ("PROPN", "NOUN"):
continue
out.append(' '.join(k.lemma_ for k in j))
print(out)
gives
['Chancellor Angela Merkel', 'minister', 'cabinet retreat', 'week way', 'ban', 'city', 'Germany', 'court', 'February', 'authority', 'diesel car']
This should give you exactly the same output as your function (the output is slightly different here but I believe this is due to different spacy versions).
If you are feeling really adventurous you could use a list comprehension
out = [' '.join(k.lemma_ for k in j)
for i, j in itertools.groupby(doc, key=lambda i: i.pos_)
if i in ("PROPN", "NOUN")]
Note I see slightly different results with different spacy versions. The output above is from spacy-2.1.8
I am experiencing a strange faulty behaviour, where a dictionary is only appended once and I can not add more key value pairs to it.
My code reads in a multi-line string and extracts substrings via split(), to be added to a dictionary. I make use of conditional statements. Strangely only the key:value pairs under the first conditional statement are added.
Therefore I can not complete the dictionary.
How can I solve this issue?
Minimal code:
#I hope the '\n' is sufficient or use '\r\n'
example = "Name: Bugs Bunny\nDOB: 01/04/1900\nAddress: 111 Jokes Drive, Hollywood Hills, CA 11111, United States"
def format(data):
dic = {}
for line in data.splitlines():
#print('Line:', line)
if ':' in line:
info = line.split(': ', 1)[1].rstrip() #does not work with files
#print('Info: ', info)
if ' Name:' in info: #middle name problems! /maiden name
dic['F_NAME'] = info.split(' ', 1)[0].rstrip()
dic['L_NAME'] = info.split(' ', 1)[1].rstrip()
elif 'DOB' in info: #overhang
dic['DD'] = info.split('/', 2)[0].rstrip()
dic['MM'] = info.split('/', 2)[1].rstrip()
dic['YY'] = info.split('/', 2)[2].rstrip()
elif 'Address' in info:
dic['STREET'] = info.split(', ', 2)[0].rstrip()
dic['CITY'] = info.split(', ', 2)[1].rstrip()
dic['ZIP'] = info.split(', ', 2)[2].rstrip()
return dic
if __name__ == '__main__':
x = format(example)
for v, k in x.iteritems():
print v, k
Your code doesn't work, at all. You split off the name before the colon and discard it, looking only at the value after the colon, stored in info. That value never contains the names you are looking for; Name, DOB and Address all are part of the line before the :.
Python lets you assign to multiple names at once; make use of this when splitting:
def format(data):
dic = {}
for line in data.splitlines():
if ':' not in line:
continue
name, _, value = line.partition(':')
name = name.strip()
if name == 'Name':
dic['F_NAME'], dic['L_NAME'] = value.split(None, 1) # strips whitespace for us
elif name == 'DOB':
dic['DD'], dic['MM'], dic['YY'] = (v.strip() for v in value.split('/', 2))
elif name == 'Address':
dic['STREET'], dic['CITY'], dic['ZIP'] = (v.strip() for v in value.split(', ', 2))
return dic
I used str.partition() here rather than limit str.split() to just one split; it is slightly faster that way.
For your sample input this produces:
>>> format(example)
{'CITY': 'Hollywood Hills', 'ZIP': 'CA 11111, United States', 'L_NAME': 'Bunny', 'F_NAME': 'Bugs', 'YY': '1900', 'MM': '04', 'STREET': '111 Jokes Drive', 'DD': '01'}
>>> from pprint import pprint
>>> pprint(format(example))
{'CITY': 'Hollywood Hills',
'DD': '01',
'F_NAME': 'Bugs',
'L_NAME': 'Bunny',
'MM': '04',
'STREET': '111 Jokes Drive',
'YY': '1900',
'ZIP': 'CA 11111, United States'}
I'm trying to write a program that allows the user to input a word then find all words of length 4 or greater hidden within that word that are in a word text file. So far my code can detect the words in the user inputted word that aren't jumbled. For example if I type in houses, the output will show house, houses, ho, us, use, uses. It should also recognize hose, hoses, shoe, shoes, hues, etc.
I know itertools is the simplest solution but I want to use a different method using only loops, dictionaries, and lists.
Here is my code so far:
def main():
filename = open('dictionary.txt').readlines()
word_list = []
for line in filename:
word_list.append(line.strip())
print 'Lets Play Words within a Word!\n'
word = raw_input('Enter a word: ')
words_left = 0
for words in word_list:
letters = list(words)
if words in word:
print words
words_left += 1
else:
False
The output format I'm trying to create should look like so:
Lets play Words within a Word!
Enter a word: exams #user inputted word
exams --- 6 words are remaining
> same #user types in guess
Found! # prints 'Found!' if above word is found in the dictionary.txt file
exams --- 5 words are remaining
> exam
Found!
exams --- 4 words are remaining
> mesa
Found!
exams --- 3 words are remaining
> quit() #if they type this command in the game will end
So my question is, after entering the base word (in the ex it's EXAMS), how do I determine the total number of words within that word and if the user inputted word guesses are in the text file? Also print if the word was found.
something like this should work...
wordlist=[list of words]
solutionlist=[]
userword=[userword[i] for i in range(len(userword))]
for word in wordlist:
inword=True
letters=[word[j] for j in range(len(word))]
for letter in set(letters):
if letters.count(letter)>userword.count(letter):
inword=False
break
if inword:
solutionlist.append(word)
for line in solutionlist:
print line
This works:
# read from file in actual implementation
all_words = [
"foo", "bar", "baz", "hose", "hoses", "shoe", "shoes", "hues", "house",
"houses", "ho", "us", "use", "uses", "shoe", "same", "exam", "mesa", "mass"]
RETAIN_ORDERING = False
def matches(inp, word):
if inp[0] == word[0]:
return (
True if len(word) == 1 else
False if len(inp) == 1 else
matches(inp[1:], word[1:]))
else:
return matches(inp[1:], word) if len(inp) >= 2 else False
# with sorting enabled, "houses" will also match "shoe"; otherwise not
def maybe_sort(x):
return x if RETAIN_ORDERING else ''.join(sorted(x))
inp = raw_input("enter a word: ")
results = [word for word in all_words if matches(maybe_sort(inp), maybe_sort(word))]
print results
Output:
$ python matches.py
enter a word: houses
['hose', 'hoses', 'shoe', 'shoes', 'hues', 'house', 'houses', 'ho', 'us', 'use', 'uses', 'shoe']
$ python matches.py
enter a word: exams
['same', 'exam', 'mesa']
If you want to avoid matches like shoe where the ordering of letters is not the same as in the input, just set RETAIN_ORDERING = True.
A naive implementation (using collections.Counter):
>>> all_words = ['foo', 'bar', 'baz', 'hose', 'hoses', 'shoe', 'shoes', 'hues', 'house', 'houses', 'ho', 'us', 'use', 'uses', 'shoe', 'same', 'exam', 'mesa', 'mass']
>>> def find_hidden(user_input):
from collections import Counter
user_word_counts = Counter(user_input)
for word in all_words:
isvalid = True
for letter, count in Counter(word).iteritems():
if user_word_counts[letter] == 0 or user_word_counts[letter] < count:
isvalid = False
break
if isvalid: yield word
>>> list(find_hidden("houses"))
['hose', 'hoses', 'shoe', 'shoes', 'hues', 'house', 'houses', 'ho', 'us', 'use', 'uses', 'shoe']
>>> list(find_hidden("exams"))
['same', 'exam', 'mesa']
Or,
Using permutations:
>>> all_words = ['foo', 'bar', 'baz', 'hose', 'hoses', 'shoe', 'shoes', 'hues', 'house', 'houses', 'ho', 'us', 'use', 'uses', 'shoe', 'same', 'exam', 'mesa', 'mass']
>>> def permutations(s, n): # could use itertools.permutations
if n == 1:
for c in s:
yield c
for i in range(len(s)):
for p in permutation(s[:i]+s[i+1:], n-1):
yield s[i] + p
>>> def find_hidden(input_str):
for word_len in range(2, len(input_str)+1):
for word in permutations(input_str, word_len):
if word in all_words:
yield word
>>> set(find_hidden("houses"))
set(['use', 'hose', 'shoes', 'houses', 'house', 'us', 'hues', 'hoses', 'uses', 'ho', 'shoe'])
>>> set(find_hidden("exams"))
set(['mesa', 'exam', 'same'])