How Connect Lines That Have Mutual Joints - python

I have a list of lines like this:
Lines = ['1', '2', '3', '4', '5', '6', '7', '8']
each line has two points I and J:
LinesDetail = {
'1': {
'I': '100',
'J': '101'},
'2': {
'I': '101',
'J': '102'},
'3': {
'I': '256',
'J': '257'},
'4': {
'I': '257',
'J': '258'},
'5': {
'I': '258',
'J': '259'},
'6': {
'I': '304',
'J': '305'},
'7': {
'I': '305',
'J': '306'},
'8': {
'I': '102',
'J': '103'}}
As you see in the picture, some of these lines have mutual points
so they are connected to each other and I need to know which lines are connected to each other.
I tried while loop but I don't have the basic idea of how to solve this kind of problems.
and the result would be:
result = [["1","2","8"],["3","4","5"],["6","7"]]
All Lines Are Vertical

This is a graph problem of finding connected components. A possible interpretation is that the outer keys are labels and the inner dictionaries are the edges (and inner dict values are the nodes). If dependency is not an issue, Python has a nice API networkx that deals with graphs. Specifically, one can use the UnionFind data structure to find the disjoint subsets.
from networkx.utils.union_find import UnionFind
# reverse the label-edge mapping to get a mapping from nodes to edge labels
edges = {}
for k, d in LinesDetail.items():
for v in d.values():
edges.setdefault(v, []).append(k)
# construct union-find data structure
c = UnionFind()
for lst in edges.values():
c.union(*lst)
# get the disjoint sets as sorted lists
result = list(map(sorted, c.to_sets()))
result
# [['1', '2', '8'], ['3', '4', '5'], ['6', '7']]

Not the most optimal solution, but putting it out there since I worked on it
LinesDetail = {
'1': {
'I': '100',
'J': '101'},
'2': {
'I': '101',
'J': '102'},
'3': {
'I': '256',
'J': '257'},
'4': {
'I': '257',
'J': '258'},
'5': {
'I': '258',
'J': '259'},
'6': {
'I': '304',
'J': '305'},
'7': {
'I': '305',
'J': '306'},
'8': {
'I': '102',
'J': '103'}}
Lines = ['1', '2', '3', '4', '5', '6', '7', '8']
results = []
for item in Lines:
match_this = LinesDetail[item]['J']
list_form = []
for key, value in LinesDetail.items():
if match_this == value['I']:
results.append([item, key])
needed_list = []
for i in range(0, len(results)-1):
if results[i][1] == results[i+1][0]:
yes_list = results[i][:1] + results[i+1]
needed_list.append(yes_list)
else:
try:
if results[i][1] == results[i+2][0]:
continue
except:
needed_list.append(results[i+1])
print(needed_list)
output:
[['1', '2', '8'], ['3', '4', '5'], ['6', '7']]

Related

Random choice function adds invinsible "0"?

I wanted to define a function that gets me the set amount of keys in a dictionary and puts it in a list.
The function though adds a "0" to the list, which is not a key and also exceeds the set amount?
I tried the code in 2 different editors (VS Code and Thonny), both did this in like 40% of the time...
The Code:
import random
def random_card(times):
chosen_card = []
for t in range(times):
chosen_card += random.choice(list(cards))
return chosen_card
cards = {
'A': 1,
'2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '10': 10,
'J': 10, 'Q': 10, 'K': 10
}
player_cards = random_card(2)
pc_cards = random_card(2)
print(f"Your cards: {player_cards}\nDealer cards: {pc_cards}")
print(list(cards))
Outputs with the "0":
Your cards: ['8', '1', '0']
Dealer cards: ['9', '1', '0']
['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
Your cards: ['Q', '1', '0']
Dealer cards: ['7', '1', '0']
['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
Your cards: ['J', '1', '0']
Dealer cards: ['Q', '4']
['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
Problem lies here
chosen_card += random.choice(list(cards))
using += cause problems for any string of length greater than 1, in your case it is 10. Consider following simple examples
cards = []
cards += "7"
print(cards) # ['7']
cards += "10"
print(cards) # ['7', '1', '0']
It did add 1 then 0 rather than 10. If you have to use += AT ANY PRICE then encase added value in list, namely
cards = []
cards += ["10"]
print(cards) # ['10']
otherwise you might use .append which is method altering list inplace, following way
cards = []
cards.append("10")
print(cards) # ['10']
This can all be fixed if you use the choices function from the random module instead. That is, simply do the following
import random
cards = {
'A': 1,
'2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '10': 10,
'J': 10, 'Q': 10, 'K': 10
}
player_cards = random.choices(list(cards),2)
pc_cards = random.choices(list(cards),2)

How to write a nested dictionary to a JSON file with specific format?

container = {'15/09/2021': {'a': '5', 'b': '7', 'c': '9', 'd': 'missing', 'e': '18'}, '16/09/2021': {'a': '6', 'b': '7', 'c': '9', 'd': '10', 'e': '12'}, '17/09/2021': {'a': '7', 'b': '8', 'c': '10', 'd': '11', 'e': 'missing'}, '18/09/2021': {'a': '9', 'b': '12', 'c': '15', 'd': 'missing', 'e': 'missing'}}
with open('output.json', 'w') as outfile:
json.dump(container, outfile, indent=4)
The result I'm getting :
This is the desired result :
I think both pictures are the same JSON, only thing is different it is the indentation.

How to reload text file into JSON after text file is edited in Python?

I want to reload my JSON after my text file is updated by reopening the text file.
import json
with open('np.txt') as np:
np_data = np.read()
np_list=json.loads(np_data)
def reopen_file():
print("reloading")
with open('np.txt') as np:
np_data = np.read()
np_list=json.loads(np_data)
y=1
while(y==1):
#np.flush()
#reopen_file()
x=input("input: ")
print("your input is" +x)
if(int(x)==1):
print(np_list)
y=input("continue?: ")
reopen_file()
print(np_list)
OUTPUT:
I update the text file before entering the value for 'y'(continue?), but the output remains the same. (I am editing the file manually)
np.txt:
{"a":"1",
"b":"2",
"c":"3",
"d":"4",
"e":"5",
"f":"6",
"g":"7",
"h":"8",
"i":"9"}
As I already commented, your code is not actually updating the same np_list you are using. A quick and dirty example to show this is just adding a print(np_list) at the end of reopen_file:
input: 1
your input is1
{'e': '5', 'b': '2', 'd': '4', 'f': '5', 'c': '3', 'a': '1', 'h': '8', 'i': '9', 'g': '7'}
continue?: 1
reloading
{'e': '5', 'b': '2', 'd': '4', 'f': '6', 'c': '3', 'a': '1', 'h': '8', 'i': '9', 'g': '7'}
{'e': '5', 'b': '2', 'd': '4', 'f': '5', 'c': '3', 'a': '1', 'h': '8', 'i': '9', 'g': '7'}
This solution works fine:
import json
def reopen_file():
with open('np.txt') as np:
np_data = np.read()
return json.loads(np_data)
np_list=reopen_file()
y=1
while(y==1):
#np.flush()
#reopen_file()
x=input("input: ")
print("your input is" +x)
if(int(x)==1):
print(np_list)
y=int(input("continue?: "))
np_list = reopen_file()
Which outputs:
Python-reload-file> python test.py
input: 1
your input is1
{'d': '4', 'b': '2', 'f': '5', 'h': '8', 'e': '5', 'a': '1', 'c': '3', 'i': '9', 'g': '7'}
continue?: 1
input: 1
your input is1
{'d': '4', 'b': '2', 'f': '6', 'h': '8', 'e': '5', 'a': '1', 'c': '3', 'i': '9', 'g': '7'}
continue?:
np_list is declared as a global variable that you can't overwrite without using the global keyword. Simplified example:
a = 3
def change_a():
a = 4
print("inside:", a)
print("outside:", a)
change_a()
print("outside after:", a)
output:
outside: 3
inside: 4
outside after: 3
example using the global keyword: (don't do this if you have other options like making a class)
a = 3
def change_a():
global a
a = 4
print("inside:", a)
print("outside:", a)
change_a()
print("outside after:", a)
output:
outside: 3
inside: 4
outside after: 4
Another small hint about how you read your json file: instead of doing
import json
with open('np.txt') as np:
np_data = np.read()
np_list=json.loads(np_data)
you can just
with open("np.txt") as np:
np_list = json.load(np)

Python Phone Number Program

I need write a program that will print to the screen all of the words (and the associated numbers) that could be generated through an 800 phone number that has the prefix 555. Remember that the numbers 1 and 0 on a keypad do not have letters associated with them.
What I have tried to so far is as follows:
alph_num_dict = {'a': '2', 'b': '2', 'c': '2',
'd': '3', 'e': '3', 'f': '3',
'g': '4', 'h': '4', 'i': '4',
'j': '5', 'k': '5', 'l': '5',
'm': '6', 'n': '6', 'o': '6',
'p': '7', 'q': '7', 'r': '7', 's': '7',
't': '8', 'u': '8', 'v': '8',
'w': '9', 'x': '9', 'y': '9', 'z': '9'}
for letter, digit in alph_num_dict.items():
print ("1.800.555." + str(digit) + str(digit) + str(digit) + str(digit), end=" ")
print (" 1.800.555." + str(letter) + str(letter) + str(letter) + str(letter))
The output that I get is:
1.800.555.2222 1.800.555.aaaa
1.800.555.2222 1.800.555.bbbb
1.800.555.2222 1.800.555.cccc
1.800.555.3333 1.800.555.dddd
1.800.555.3333 1.800.555.eeee
1.800.555.3333 1.800.555.ffff
1.800.555.4444 1.800.555.gggg
1.800.555.4444 1.800.555.hhhh
1.800.555.4444 1.800.555.iiii
1.800.555.5555 1.800.555.jjjj
1.800.555.5555 1.800.555.kkkk
1.800.555.5555 1.800.555.llll
1.800.555.6666 1.800.555.mmmm
1.800.555.6666 1.800.555.nnnn
1.800.555.6666 1.800.555.oooo
1.800.555.7777 1.800.555.pppp
1.800.555.7777 1.800.555.qqqq
1.800.555.7777 1.800.555.rrrr
1.800.555.7777 1.800.555.ssss
1.800.555.8888 1.800.555.tttt
1.800.555.8888 1.800.555.uuuu
1.800.555.8888 1.800.555.vvvv
1.800.555.9999 1.800.555.wwww
1.800.555.9999 1.800.555.xxxx
1.800.555.9999 1.800.555.yyyy
1.800.555.9999 1.800.555.zzzz
This is only part of the output that I need. I need to be able to output all of the other possible combinations (there are 456,976 of them.)
I am having trouble figuring out how to get the output for all of the possible combinations.
To clear things up, I need the output to start off looking something like:
1.800.555.2222 1.800.555.aaaa
1.800.555.2222 1.800.555.aaab
1.800.555.2222 1.800.555.aaac
1.800.555.2223 1.800.555.aaad
1.800.555.2223 1.800.555.aaae
1.800.555.2223 1.800.555.aaaf
Any help with this would be greatly appreciated.
You might want to take a look at the permutations function.
alph_num_dict = {'a': '2', 'b': '2', 'c': '2',
'd': '3', 'e': '3', 'f': '3',
'g': '4', 'h': '4', 'i': '4',
'j': '5', 'k': '5', 'l': '5',
'm': '6', 'n': '6', 'o': '6',
'p': '7', 'q': '7', 'r': '7', 's': '7',
't': '8', 'u': '8', 'v': '8',
'w': '9', 'x': '9', 'y': '9', 'z': '9'}
from itertools import permutations
all_numbers = permutations(alph_num_dict, 4):
for number in all_numbers:
# TODO: Iterate through all_numbers and do translation

Dictionary output on one line

I'm a beginner learning Python 3.3 through http://GrokLearning.com
My objective is to write a Word2SMS program. The program tells the user which "number buttons" to press on basic cell phones (non-smartphones) in order to spell out a given word. The input word will be given in all uppercase letters - no numbers or punctuation. Assume the phone can perfectly predict the word given corresponding number input from the user.
Sample goal output:
> GROK
4765
My code:
KEYPAD = {'A': '2', 'B': '2', 'C': '2', 'D': '3', 'E': '3', 'F': '3', 'G': '4', 'H': '4', 'I': '4', 'J': '5', 'K': '5', 'L': '5', 'M': '6', 'N': '6', 'O': '6', 'P': '7', 'Q': '7', 'R': '7', 'S': '7', 'T': '8', 'U': '8', 'V': '8', 'W': '9', 'X': '9', 'Y': '9', 'Z': '9'}
word = input("Enter word: ")
for key in word:
print(KEYPAD[key], end='')
The result:
My code returns the same digits, all on one line, with no whitespace between the digits, just as I want. However, I receive this notification: Your output is missing a trailing newline character.
I've tried adding '\n' to add a new line at the end; this gives me unexpected character after line continuation character SyntaxError.
Adding ' ' at the end results in one digit per line.
For reference, I have gone through all of the free modules, but not any of the paid ones. Since my knowledge is limited, please explain your answer in simple terms.
You just need to print out one newline after you process the input string:
KEYPAD = {'A': '2', 'B': '2', 'C': '2', 'D': '3', 'E': '3', 'F': '3', 'G': '4', 'H': '4', 'I': '4', 'J': '5', 'K': '5', 'L': '5', 'M': '6', 'N': '6', 'O': '6', 'P': '7', 'Q': '7', 'R': '7', 'S': '7', 'T': '8', 'U': '8', 'V': '8', 'W': '9', 'X': '9', 'Y': '9', 'Z': '9'}
word = input("Enter word: ")
for key in word:
print(KEYPAD[key], end='') #<-- this line suppresses the newline output
print() #<-- this adds the required newline at the end of all the characters
For an even shorter solution:
KEYPAD = {'A': '2', 'B': '2', 'C': '2', 'D': '3', 'E': '3', 'F': '3', 'G': '4', 'H': '4', 'I': '4', 'J': '5', 'K': '5', 'L': '5', 'M': '6', 'N': '6', 'O': '6', 'P': '7', 'Q': '7', 'R': '7', 'S': '7', 'T': '8', 'U': '8', 'V': '8', 'W': '9', 'X': '9', 'Y': '9', 'Z': '9'}
word = input("Enter word: ")
print(''.join([KEYPAD[k] for k in word])) # This will join all the buttons together and print with an automatic newline
By the way your error "unexpected character after line continuation character SyntaxError." means that you put the \n outside of quotes. \ outside of quotes means continued on the next line so there should not be any text other than newline after it.

Categories

Resources