Ranges as values in dictionary and using these in if else statement - python

I am new to python basically, I want this dictionary:
ages = {
"toddler" : range(0,2),
"kid" : range(3,12),
"teen" : range(13,19),
"young adult" : range(20,25),
"adult" : range(26,39),
"middle-aged" : range(40,60),
"old" : range(61,99)
}
I have a target_age variable which holds the random value in any of the keys in the above mentioned dictionary:
target_age = random.choice(list(ages))
my api is going to return an "age" which I want to compare if its in the range of the randomized "target_age" variable
How should I code my "if and else statement" if I want for example the returned_age is 25 and the target_age is "young adult" then it should satisfy the condition otherwise it should return false

returned_age in ages[target_age], as mentioned by #khelwood above, sounds like it would accomplish what you want:
ages = {
'toddler': range(0,3),
'kid': range(3,13),
'teen': range(13,20),
'young adult': range(20,26),
'adult': range(26,40),
'middle-aged': range(40,61),
'old': range(61,99)
}
# generate a random target_age
target_age = np.random.choice(list(ages))
# suppose the returned_age from the API is 25
returned_age = 25
print('target_age = ' + str(target_age))
print('returned_age = ' + str(returned_age))
print('returned_age in target_age? ' + str(returned_age in ages[target_age]))
Here is the output from one particular run:
target_age = old
returned_age = 25
returned_age in target_age? False

Related

iteration over 2d list in python and printing headings for each element

I am trying to work out how to iterate over a list and print out each item with a print statement describing what element is. my project is to create a user management system and print out something similar to the image I have attached.
The output I am trying to produce
The output I am getting
My code:
records = 0
userFirst = ["John"]
userLast = ["Doe"]
autoUsername = ["Johndoe91"]
autoPassword = ["123456789"]
hiddenPassword = ["*****789"]
userRole = ["User"]
userDept = ["Administration"]
users = []
confidentialUserDetails = []
users.append(userFirst + userLast + userRole + userDept + autoUsername + autoPassword)
confidentialUserDetails.append(users)
for row in range(len(confidentialUserDetails)):
records += 1
print("-" * 25)
print("Record: ", records)
for col in range(len(confidentialUserDetails[row])):
print(confidentialUserDetails[row][col])
Any help would be greatly appreciated. :)
Your data structures are unusual. I'm assuming that those lists are going to be provided to your code somehow and will, in practice, have multiple user details appended to them so that they are all the same length.
Anyhow, you can achieve the output you're looking for with some readable f-strings like this:
from functools import reduce
userFirst = ["John"]
userLast = ["Doe"]
autoUsername = ["Johndoe91"]
autoPassword = ["123456789"]
hiddenPassword = ["*****789"]
userRole = ["User"]
userDept = ["Administration"]
for row in range(len(userFirst)):
s = (f"""\
Name : {userFirst[row]} {userLast[row]}
Role : {userRole[row]}
Department : {userDept[row]}
Username : {autoUsername[row]}
Password : {hiddenPassword[row]}""")
maxlen = reduce(lambda x,y: max(x, len(y)), s.split("\n"), 0)
print(f"{s}\n{'-'*maxlen}\n")
Output:
Name : John Doe
Role : User
Department : Administration
Username : Johndoe91
Password : *****789
------------------------------
I created a dictionary called user instead of your list and after that I appended it to the second list and finally I printed the key and the value of the dictionary.
Also to get the full name I joined userFirst and userLast as string.
Code:
records = 0
userFirst = ["John"]
userLast = ["Doe"]
autoUsername = ["Johndoe91"]
autoPassword = ["123456789"]
hiddenPassword = ["*****789"]
userRole = ["User"]
userDept = ["Administration"]
confidentialUserDetails = [] # 2d list for asterisked passwords
users={'Name' : [' '.join(userFirst + userLast)] ,'Role' : userRole , 'Departement' : userDept ,'Username' : autoUsername ,'Password' : hiddenPassword }
confidentialUserDetails.append(users)
for user in confidentialUserDetails:
records += 1
print("-" * 25)
print("Record: ", records)
for ele,v in user.items():
print(ele,':',v[0])
Output:
-------------------------
Record: 1
Name : John Doe
Role : User
Departement : Administration
Username : Johndoe91
Password : *****789
Using a dictionary or f strings like the two other answers suggested is probably the best. But if you just want to use your current code to print your desired output, you can simply grab each item by its index number in your print statement.
Change the line:
print(confidentialUserDetails[row][col])
To something like this:
print("Name : ", confidentialUserDetails[row][col][0], confidentialUserDetails[row][col][1])
print("Role: : ", confidentialUserDetails[row][col][2])
Output:
-------------------------
Record: 1
Name : John Doe
Role: : User

create dict keys depending on the number of times the same value occurs

I have a dict as below, if the same value is found more tahn once then the dict key must be created with incremental numbering.
TT = {
"TYPE_1" : ['ERROR'],
"TYPE_2": ['FATAL'],
"TYPE_3" : ["TIME_OUT"],
"TYPE_4" : ['SYNTAX'],
"TYPE_5" : ['COMPILE'],
}
m1 = "ERROR the input is not proper"
m2 = "This should have not occured FATAL"
m3 = "Sorry TIME_OUT"
m4 = "SYNTAX not proper"
m5 = "u r late its TIME_OUT"
The value "TIME_OUT" occur twice in the search.
count = 0
for key in TT.keys():
print(key)
Key_1 = key
while key_1 in TT:
count = count+1
key_1 = key + "_{}".format(count)
The above code gives error Key_1 not defined.
Expected OUTPUT:
if the same value is occuring more than once then the dict key should be created with incremental numbering "TYPE_3_1" : ["TIME_OUT"],
TT = {
"TYPE_1" : ['ERROR'],
"TYPE_2": ['FATAL'],
"TYPE_3" : ["TIME_OUT"],
"TYPE_3_1" : ["TIME_OUT"],
"TYPE_4" : ['SYNTAX'],
"TYPE_5" : ['COMPILE'],
}
Please suggest on this.
There can be a much efficient way of solving this if you can rethink about some of the data structure but if that is not an option you may be able to try this.
inputs = ["ERROR the input is not proper",
"This should have not occured FATAL",
"Sorry TIME_OUT",
"SYNTAX not proper",
"u r late its TIME_OUT"]
basic_types = {
"TYPE_1" : ['ERROR'],
"TYPE_2": ['FATAL'],
"TYPE_3" : ["TIME_OUT"],
"TYPE_4" : ['SYNTAX'],
"TYPE_5" : ['COMPILE'],
}
type_counts = {}
results = {}
for sentence in inputs:
for basic_type in basic_types:
if basic_types.get(basic_type)[0] in sentence:
type_counts[basic_type] = type_counts.get(basic_type, 0) + 1
if type_counts[basic_type] == 1:
results[basic_type] = [basic_types.get(basic_type)[0]]
else:
results[basic_type+"_{}".format(type_counts[basic_type] - 1)] = [basic_types.get(basic_type)[0]]
print(results)

Python 'key error' while building dictionary dynamically (On the fly)

I get the error onthis line of code -
result_dict['strat'][k]['name'] = current_comps[0].strip()
The error is : Keyerror: 'strat'
I have an input line
PERSON1 ## CAR1 # ENTRY : 0 | EXIT : 0 ## CAR2 # M1 : YES : 10/01/17 02:00 | M2 : NO : 10/02/16 03:00 | M3 : NO : 05/07/17 11:00 | M4 : YES : 01/01/16 03:00 ## TRUCK # M3 : NO : 03/01/17 03:45 | M23 : NO : 01/01/14 07:00 | M27 : YES : 02/006/18 23:00
I 'm looking to parse this input to generate the output detailed below. As part of this, I'm trying to build a dictionary inserting both keys & values dynamically. I'm having a lot of problems doing this.
Could I please request help on this?
Here is what I've tried so far -
# File read
f = open('input_data', 'r')
file_cont = f.read().splitlines()
f.close()
#json template
# Initialize dictionary
result_arr = []
result_dict = {}
k = 0
for item in file_cont:
strat = item.split('##')
result_dict['Person'] = strat[0].strip()
j = 1
while j < len(strat):
# Split various components of the main line
current_comps = strat[j].split('#')
# Name of strat being parsed
result_dict['strat'][k]['name'] = current_comps[0].strip()
# tfs across the various time frames
tfs = current_comps[1].split('|')
# First travel mode
if current_comps[0].strip() == 'CAR1':
temp_low_arr = tfs[0].split(':')
temp_high_arr = tfs[1].split(':')
result_dict['strat'][k]['Entry'] = temp_low_arr[1].strip()
result_dict['strat'][k]['Exit'] = temp_high_arr[1].strip()
# Second travel mode
elif current_comps[0].strip() == 'CAR2':
z = 0
while z < len(tfs):
# Split components of the sign
sign_comp_car_2 = tfs[z].split(':')
result_dict['strat'][k]['tf'][z]['path'] = sign_comp_ma_cross[0].strip()
result_dict['strat'][k]['tf'][z]['sign'] = sign_comp_ma_cross[1].strip()
result_dict['strat'][k]['tf'][z]['sign_time'] = sign_comp_ma_cross[2].strip()
z += 1
# Third travel mode
elif current_comps[0].strip() == 'CAR3':
b = 0
while b < len(tfs):
# Split components of the sign
sign_car_3 = tfs[z].split(':')
result_dict['strat'][k]['tf'][b]['path'] = sign_all_term[0].strip()
result_dict['strat'][k]['tf'][b]['sign'] = sign_all_term[1].strip()
result_dict['strat'][k]['tf'][b]['sign_time'] = sign_all_term[2].strip()
b += 1
j += 1
k += 1
Expected output
[{
"Person":"",
"Transport":[
{
"Name":"CAR1",
"Entry":"0",
"Exit":"0"
},
{
"name":"CAR2:",
"tf":[
{
"path":"M1",
"sign":"YES",
"sign_time":"10/01/17 02:00"
},
{
"path":"M2",
"sign":"NO",
"sign_time":"10/02/16 03:00"
},
{
"path":"M3",
"sign":"NO",
"sign_time":"05/07/17 11:00"
},
{
"path":"M4",
"sign":"YES",
"sign_time":"01/01/16 03:00"
}
]
},
{
"name":"CAR3",
"tf":[
{
"path":"M3",
"sign":"NO",
"sign_time":"03/01/17 03:45"
},
{
"path":"M23",
"sign":"NO",
"sign_time":"01/01/14 07:00"
},
{
"path":"M27",
"sign":"Yes",
"sign_time":"02/006/18 23:00"
}
]
}
]
}]
The issue is when you try to assign the ['name'] field in result_dict['strat'][k] when result_dict['strat'][k] hasn't been initialized yet. Before you run your for-loop, the dictionary has no key called strat.
Now you could have done something like result_dict['strat'] = dict() (assigning an object to that key in the dict), but when you further subscript it using result_dict['strat'][k], it will try to resolve that first, by accessing result_dict['strat'], expecting either a subscriptable collection or a dictionary in return. However, since that key doesn't exist yet, it throws you the error.
What you could do instead is initialize a default dictionary:
from collections import defaultdict
...
resultdict = defaultdict(dict)
...
Otherwise, in your existing code, you could initialize a dict within result_dict before entering the loop.

printing from nested dictionaries in classes

Having isues figuring out why this particular setup isnt working.
class market(object):
def __init__(self, market, coin):
self.coin = coin
self.market = market
req = requests.get(f"http://bittrex.com/api/v1.1/public/getticker?market={market}-{coin}")
sum = requests.get(f"https://bittrex.com/api/v1.1/public/getmarketsummary?market={market}-{coin}")
self.address = req.json()
self.marketsum = sum.json()
def ticker(self):
while True:
print(self.address["result"])
time.sleep(5)
def marketsummary(self):
print(f"Market Summary for {coin}")
print('_' * 20)
print("Market Name: ", self.marketsum['result']['MarketName'])
print("High: ", self.marketsum['result']['High']))
print("Low: ", self.marketsum['result']['Low'])
print("Volume: ", self.marketsum['result']['Volume'])
print("Last: ", self.marketsum['result']['Last'])
print("BaseVolume: ", self.marketsum['result']['BaseVolume'])
print("TimeStamp: ", self.marketsum['result']['TimeStamp'])
print("Bid: ", self.marketsum['result']['Bid'])
print("Ask: ", self.marketsum['result']['Ask'])
print("OpenBuyOrders: ", self.marketsum['result']['OpenBuyOrders'])
print("OpenSellOrders: ", self.marketsum['result']['OpenSellOrders'])
print("Previous Day: ", self.marketsum['result']['PrevDay'])
print("Created: ", self.marketsum['result']['Created'])
print("DisplayMarketName: ", self.marketsum['result']['DisplayMarketName'])`
Ive previously used this method with static(?jaron?) variables in if statements, such as
usdt_ticker = requests.get("https://bittrex.com/api/v1.1/public/getticker?market=USDT-ADA")
btc_ticker = requests.get("https://bittrex.com/api/v1.1/public/getticker?market=BTC-ADA")
eth_ticker = requests.get("https://bittrex.com/api/v1.1/public/getticker?market=ETH-ADA")
print("Which trade pairing would you like for this coin?")
tradepair = input("> ")
if str.lower(tradepair) == "usdt" or "tether":
actual_ticker = usdt_ticker.json()
elif str.lower(tradepair) == "btc" or "bitcoin":
actual_ticker = btc_ticker.json()
elif str.lower(tradepair) == "eth" or "ethereum":
actual_ticker = eth_ticker.json()
else:
print("Sorry that trading pair isnt currently being monitored by this system")
print("Now viewing Cardano /", str.upper(tradepair), " trading." )
current_price = actual_ticker["result"]["Last"]
but with the self.marketsum['result']['MarketName'] its not working. If theres any input as to why this is happening and how to fix it I would be greatly appreciative. The error I am getting is
TypeError: list indicies must be integers or slices, not str
From the developer's guide, the json structure of a response from /public/getmarketsummary looks like:
{
"success" : true,
"message" : "",
"result" : [{
"MarketName" : "BTC-LTC",
"High" : 0.01350000,
"Low" : 0.01200000,
"Volume" : 3833.97619253,
"Last" : 0.01349998,
"BaseVolume" : 47.03987026,
"TimeStamp" : "2014-07-09T07:22:16.72",
"Bid" : 0.01271001,
"Ask" : 0.01291100,
"OpenBuyOrders" : 45,
"OpenSellOrders" : 45,
"PrevDay" : 0.01229501,
"Created" : "2014-02-13T00:00:00",
"DisplayMarketName" : null
}
]
}
Notice the result is actually a list containing a single element. They don't state why it is in a list and I can't get it to return a list with more than one element.
For now, it should be fine to change the lines accessing marketsum from
self.marketsum['result']['last']
to
self.marketsum['result'][0]['last']
Probably also add a check that the list is not empty.

How to search for multiple data from multiple lines and store them in dictionary?

Say I have a file with the following:
/* Full name: abc */
.....
.....(.....)
.....(".....) ;
/* .....
/* .....
..... : "....."
}
"....., .....
Car : true ;
House : true ;
....
....
Age : 33
....
/* Full name: xyz */
....
....
Car : true ;
....
....
Age : 56
....
I am only interested in full name, car, house and age of each person. There are many other lines of data with different format between the variable/attritbute that I am interested.
My code so far:
import re
initial_val = {'House': 'false', 'Car': 'false'}
with open('input.txt') as f:
records = []
current_record = None
for line in f:
if not line.strip():
continue
elif current_record is None:
people_name = re.search('.+Full name ?: (.+) ', line)
if people_name:
current_record = dict(initial_val, Name = people_name.group(1))
else:
continue
elif current_record is not None:
house = re.search(' *(House) ?: ?([a-z]+)', line)
if house:
current_record['House'] = house.group(2)
car = re.search(' *(Car) ?: ?([a-z]+)', line)
if car:
current_record['Car'] = car.group(2)
people_name = re.search('.+Full name ?: (.+) ', line)
if people_name:
records.append(current_record)
current_record = dict(initial_val, Name = people_name.group(1))
print records
What I get:
[{'Name': 'abc', 'House': 'true', 'Car': 'true'}]
My question:
How am I suppose to extract the data and store it in a dictionary like:
{'abc': {'Car': true, 'House': true, 'Age': 33}, 'xyz':{'Car': true, 'House': false, 'Age': 56}}
My purpose:
check whether each person has car, house and age, if no then return false
The I could print them in a table like this:
Name Car House Age
abc true true 33
xyz true false 56
Note that I am using Python 2.7 and I do not know what is the actual value of each variable/attribute (Eg. abc, true, true, 33) of each person.
What is the best solution to my question? Thanks.
Well, you just have to keep track of the current record:
def parse_name(line):
# first remove the initial '/* ' and final ' */'
stripped_line = line.strip('/* ')
return stripped_line.split(':')[-1]
WANTED_KEYS = ('Car', 'Age', 'House')
# default values for when the lines are not present for a record
INITIAL_VAL = {'Car': False, 'House': False, Age: -1}
with open('the_filename') as f:
records = []
current_record = None
for line in f:
if not line.strip():
# skip empty lines
continue
elif current_record is None:
# first record in the file
if line.startswith('/*'):
current_record = dict(INITIAL_VAL, name=parse_name(line))
else:
# this should probably be an error in the file contents
continue
elif line.startswith('/*'):
# this means that the current record finished, and a new one is starting
records.append(current_record)
current_record = dict(INITIAL_VAL, name=parse_name(line))
else:
key, val = line.split(':')
if key.strip() in WANTED_KEYS:
# we want to keep track of this field
current_record[key.strip()] = val.strip()
# otherwise just ignore the line
print('Name\tCar\tHouse\tAge')
for record in records:
print(record['name'], record['Car'], record['House'], record['Age'], sep='\t')
Note that for Age you may want to convert it to an integer using int:
if key == 'Age':
current_record['Age'] = int(val)
The above code produces a list of dictionaries, but it is easy enough to convert it to a dictionary of dicts:
new_records = {r['name']: dict(r) for r in records}
for val in new_records.values():
del val['name']
After this new_records will be something like:
{'abc': {'Car': True, 'House': True, Age: 20}, ...}
If you have other lines with a different format in between the interesting ones you can simply write a function that returns True or False depending on whether the line is in the format you require and use it to filter the lines of the file:
def is_interesting_line(line):
if line.startswith('/*'):
return True
elif ':' in line:
return True
for line in filter(is_interesting_line, f):
# code as before
Change is_interesting_line to suit your needs. In the end, if you have to handle several different formats etc. maybe using a regex would be better, in that case you could do something like:
import re
LINE_REGEX = re.compile(r'(/\*.*\*/)|(\w+\s*:.*)| <other stuff>')
def is_interesting_line(line):
return LINE_REGEX.match(line) is not None
If you want you can obtain fancier formatting for the table, but you probably first need to determine the maximum length of the name etc. or you can use something like tabulate to do that for you.
For example something like (not tested):
max_name_length = max(max(len(r['name']) for r in records), 4)
format_string = '{:<{}}\t{:<{}}\t{}\t{}'
print(format_string.format('Name', max_name_length, 'Car', 5, 'House', 'Age'))
for record in records:
print(format_string.format(record['name'], max_name_length, record['Car'], 5, record['House'], record['Age']))

Categories

Resources