Python Forum
Subtracting values between two dictionaries/ floating point numbers - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Subtracting values between two dictionaries/ floating point numbers (/thread-16526.html)



Subtracting values between two dictionaries/ floating point numbers - FloppyPoppy - Mar-03-2019

Hello everybody hope your all doing great :D,

I am new to learning python and challenged myself to make a small program for a game i like to play called Star Citizen, the purpous of the program is to take two inputs, player location and player destination. It will then take those two sets of data and calculate from a dictionary what the user can buy at their current location and sell at their destination and what would be the most profitable.

I am running into an issue when it comes calculating this. I believe im probably going about this all wrong so please don't worry about telling me to start from scratch with different ideas.

Here is the code so far:

#### taking user information
user_purchase_location = input("Were are you planning to buy your goods?").lower()
user_sale_destination = input("Where are you planning to sell your goods?").lower()

#### dicts of items available to buy and sell at locations along with UEC price.
buying_olisar = {'Medical Supply': 17.01,}
selling_olisar = {'Agricium': 25.60, 'Aluminum': 1.25, 'Beryl': 4.26, 'Chlorine': 1.57, 'Corundum': 2.53, 'Diamond': 6.90, 'Distilled Spirits': 4.95, 'Fluorine': 2.80, 'Gold': 6.07, 'Hydrogen': 1.02, 'Iodine': 0.41, 'Laranite': 28.91, 'Processed Food': 1.39, 'Quartz': 1.44, 'Scrap': 1.67, 'Stims': 3.40, 'Titanium': 8.27, 'Tungsten': 3.90,}
buying_levski = {'Agricultural Supply': 1.11, 'Aluminum': 1.20, 'Hydrogen': 0.98, 'Iodine': 0.38, 'Quartz': 1.37,}
selling_levski = {'Agricium': 25.60, 'Altruciatoxine': 11.63, 'Beryl': 4.25, 'Chlorine': 1.56, 'Corundum': 2.53, 'Diamond': 6.07, 'Distilled Spirits': 4.95, 'Fluorine': 2.80, 'Gold': 6.07, 'Laranite': 28.25, 'Medical Supply': 18.00, 'Processed Food': 1.38, 'Scrap': 1.68, 'Stims': 3.40, 'Titanium': 8.27, 'Tungsten': 3.90, 'Widdow': 24.00,}

#### Sorting the dict into ascending value instead of alphabetical
sort_buying_olisar = sorted(buying_olisar, key=lambda tup: tup[1])
sort_selling_olisar = sorted(selling_olisar, key=lambda tup:(tup[1], tup[0]))
sort_buying_levski = sorted(buying_levski, key=lambda tup: tup[1])
sort_selling_levski = sorted(selling_levski, key=lambda tup:(tup[1], tup[0]))


#### picking two dicts (buy/sell) and filtering them to print only common elements.
def common(curr, other):
    return set(curr.keys()).intersection(set(other.keys()))
tradable_items = common(buying_levski, selling_olisar)


#### calculating the prices between possible sales.
prices = {k: selling_olisar[k] - buying_levski[k] for k in tradable_items}


print(prices)
When i run this the figures are coming out as floating point numbers for example:

Quote:Were are you planning to buy your goods?levski
Where are you planning to sell your goods?olisar
{'Quartz': 0.06999999999999984, 'Hydrogen': 0.040000000000000036, 'Iodine': 0.02999999999999997, 'Aluminum': 0.050000000000000044}

What i a can't figure out is how to #1 have these floating point numbers be not so large and #2 how to then print out the item in the dictionary that holds the largest number.

Any guidance would be massively appreciated.

Thanks any questions please ask and sorry if the formatting isn't perfect i am a really new to this :).


RE: Subtracting values between two dictionaries/ floating point numbers - snippsat - Mar-03-2019

(Mar-03-2019, 06:50 PM)FloppyPoppy Wrote: how to #1 have these floating point numbers be not so large
Use string formatting,f-string Python 3.6-->.
>>> d = {'Quartz': 0.06999999999999984, 'Hydrogen': 0.040000000000000036, 'Iodine': 0.02999999999999997, 'Aluminum': 0.050000000000000044}
>>> print(f'Value of Quartz is {d["Quartz"]:.2f}')
Value of Quartz is 0.07
(Mar-03-2019, 06:50 PM)FloppyPoppy Wrote: #2 how to then print out the item in the dictionary that holds the largest number
>>> d = {'Quartz': 0.06999999999999984, 'Hydrogen': 0.040000000000000036, 'Iodine': 0.02999999999999997, 'Aluminum': 0.050000000000000044}
>>> max(d, key=d.get)
'Quartz'



RE: Subtracting values between two dictionaries/ floating point numbers - FloppyPoppy - Mar-03-2019

Hello snippsat,

Thank you very much for your help this has opened my eyes to a couple of new ways to do things in python. Here is the bottom of the code that i have got working with some manipulation and further research.

import operator
most_profitable_resourse = max(prices.items(), key=operator.itemgetter(1))[0]

profit_ammount = prices
profit_sorted = (f'{profit_ammount["Quartz"]:.2f}')


print("The most profitable item to buy at " + user_purchase_location + " is " + most_profitable_resourse + " and will make a net profit of " + profit_sorted + " per unit when sold at " + user_sale_destination + ".")

Were are you planning to buy your goods?Levski
Where are you planning to sell your goods?Olisar
The most profitable item to buy at levski is Quartz and will make a net profit of 0.07 per unit when sold at olisar.
Im going to spend some more time working on this code and adding in more locations once i am 100% happy the calculations are all complete i will post the code for anyone who wants to have a play :).


RE: Subtracting values between two dictionaries/ floating point numbers - snippsat - Mar-03-2019

You can and should use f-string everywhere,eg your line 8.
Also think of line length,line 8 is now 215 characters in length.
PEP-8 say 79 characters line length,but i would say that 90'ish is okay.
Example:
user_purchase_location = 'Mall'
most_profitable_resourse = 'Diamond' 
profit_sorted = '99'
user_sale_destination = 'Gold Shop'

print(
f"The most profitable item to buy at {user_purchase_location} is {most_profitable_resourse}\n\
and will make a net profit of {profit_sorted} per unit when sold at {user_sale_destination}"
)
Output:
The most profitable item to buy at Mall is Diamond and will make a net profit of 99 per unit when sold at Gold Shop



RE: Subtracting values between two dictionaries/ floating point numbers - FloppyPoppy - Mar-04-2019

(Mar-03-2019, 10:52 PM)snippsat Wrote: You can and should use f-string everywhere,eg your line 8.
Also think of line length,line 8 is now 215 characters in length.
PEP-8 say 79 characters line length,but i would say that 90'ish is okay.
Example:
user_purchase_location = 'Mall'
most_profitable_resourse = 'Diamond' 
profit_sorted = '99'
user_sale_destination = 'Gold Shop'

print(
f"The most profitable item to buy at {user_purchase_location} is {most_profitable_resourse}\n\
and will make a net profit of {profit_sorted} per unit when sold at {user_sale_destination}"
)
Output:
The most profitable item to buy at Mall is Diamond and will make a net profit of 99 per unit when sold at Gold Shop

Thanks for that information i will be sure to try and incorporate F strings going forward. I have changed the program to reflect your advice.

Here is how the code is looking now

#### taking user information
user_purchase_location = input(f"Where are you planning to buy your goods?").lower()
user_sale_destination = input(f"Where are you planning to sell your goods?").lower()

#### dicts of items available to buy and sell at locations along with UEC price.
buying_olisar = {'Medical Supply': 17.01,}
selling_olisar = {'Agricium': 25.60, 'Aluminum': 1.25, 'Beryl': 4.26, 'Chlorine': 1.57, 'Corundum': 2.53, 'Diamond': 6.90, 'Distilled Spirits': 4.95, 'Fluorine': 2.80, 'Gold': 6.07, 'Hydrogen': 1.02, 'Iodine': 0.41, 'Laranite': 28.91, 'Processed Food': 1.39, 'Quartz': 1.44, 'Scrap': 1.67, 'Stims': 3.40, 'Titanium': 8.27, 'Tungsten': 3.90,}
buying_levski = {'Agricultural Supply': 1.11, 'Aluminum': 1.20, 'Hydrogen': 0.98, 'Iodine': 0.38, 'Quartz': 1.37,}
selling_levski = {'Agricium': 25.60, 'Altruciatoxine': 11.63, 'Beryl': 4.25, 'Chlorine': 1.56, 'Corundum': 2.53, 'Diamond': 6.07, 'Distilled Spirits': 4.95, 'Fluorine': 2.80, 'Gold': 6.07, 'Laranite': 28.25, 'Medical Supply': 18.00, 'Processed Food': 1.38, 'Scrap': 1.68, 'Stims': 3.40, 'Titanium': 8.27, 'Tungsten': 3.90, 'Widdow': 24.00,}
buying_grim_hex = {'Chlorine': 1.44, 'Flurine': 2.63, 'Hydrogen': 0.97, 'Iodine': 0.34}
selling_grim_hex = {'Altruciatoxine': 11.80, 'distilled spirits': 4.95, 'medical suppies': 18.05, 'processed food': 1.36, 'stims': 3.40, 'Widdow': 24.0}


#### Sorting the dict into ascending value instead of alphabetical
sort_buying_olisar = sorted(buying_olisar, key=lambda tup: tup[1])
sort_selling_olisar = sorted(selling_olisar, key=lambda tup:(tup[1], tup[0]))
sort_buying_levski = sorted(buying_levski, key=lambda tup: tup[1])
sort_selling_levski = sorted(selling_levski, key=lambda tup:(tup[1], tup[0]))
sort_buying_grim_hex = sorted(buying_arc_corp_mining_area_157, key=lambda tup: tup[1])
sort_selling_grim_hex = sorted(selling_arc_corp_mining_area_157, key=lambda tup:(tup[1], tup[0]))

#### picking two dicts (buy/sell) and filtering them to print only common elements.
def common(curr, other):
    return set(curr.keys()).intersection(set(other.keys()))
tradable_items = common(buying_levski, selling_olisar)

#### calculating the prices between possible sales.
prices = {k: selling_olisar[k] - buying_levski[k] for k in tradable_items}

#### finding the most profitable material
import operator
most_profitable_resourse = max(prices.items(), key=operator.itemgetter(1))[0]

#### sorting and printing the most profitable purchase.
profit_ammount = prices
profit_sorted = (f'{profit_ammount[most_profitable_resourse]:.2f}')
print(
f"The most profitable item to buy at {user_purchase_location.title()} is {most_profitable_resourse.title()}\n\
and will make a net profit of {profit_sorted} per unit when sold at {user_sale_destination.title()}"
What i am trying to do now is alter these two lines to reflect any input from the user opposed to just focusing on the two. This is why i added in the third area "grim_hex"

tradable_items = common(buying_levski, selling_olisar)
prices = {k: selling_olisar[k] - buying_levski[k] for k in tradable_items}
i have tried to create a second variable as follows:
user_purchase_location_1 = 'buying_'+user_purchase_location+''
user_sale_destination_1 = 'selling_'+user_sale_destination+''
these produce the correct information but wont work when added into the code as below as they are interpreted as strings:

def common(curr, other):
    return set(curr.keys()).intersection(set(other.keys()))
tradable_items = common(user_purchase_location_1, user_sale_destination_1)

prices = {k: user_sale_destination_1[k] - user_purchase_location_1[k] for k in tradable_items}
When im running it like that i get this error:

Traceback (most recent call last):
File "/home/floppypoppy/PycharmProjects/Star Citizen Trading Program/Star Citizen trading NEW.py", line 33, in <module>
tradable_items = common(user_purchase_location_1, user_sale_destination_1)
File "/home/floppypoppy/PycharmProjects/Star Citizen Trading Program/Star Citizen trading NEW.py", line 32, in common
return set(curr.keys()).intersection(set(other.keys()))
AttributeError: 'str' object has no attribute 'keys'

Sorry for the wall of text just trying to offer up as much information on what i am doing as possible. Is there anything you can suggest i research to to make the above work?

Again thanks for any help and kindest regards,

Harry (FP)


RE: Subtracting values between two dictionaries/ floating point numbers - snippsat - Mar-04-2019

Dictionary do not give you a free pass on line length Wink
Here is formatted code,i use VS Code and black set to format code.
So i not done all this manually.
import operator

#### taking user information
user_purchase_location = 'Mall'
user_sale_destination = 'Gold Shop'

#### dicts of items available to buy and sell at locations along with UEC price.
buying_olisar = {"Medical Supply": 17.01}

selling_olisar = {
    "Agricium": 25.60,
    "Aluminum": 1.25,
    "Beryl": 4.26,
    "Chlorine": 1.57,
    "Corundum": 2.53,
    "Diamond": 6.90,
    "Distilled Spirits": 4.95,
    "Fluorine": 2.80,
    "Gold": 6.07,
    "Hydrogen": 1.02,
    "Iodine": 0.41,
    "Laranite": 28.91,
    "Processed Food": 1.39,
    "Quartz": 1.44,
    "Scrap": 1.67,
    "Stims": 3.40,
    "Titanium": 8.27,
    "Tungsten": 3.90,
}

buying_levski = {
    "Agricultural Supply": 1.11,
    "Aluminum": 1.20,
    "Hydrogen": 0.98,
    "Iodine": 0.38,
    "Quartz": 1.37,
}
selling_levski = {
    "Agricium": 25.60,
    "Altruciatoxine": 11.63,
    "Beryl": 4.25,
    "Chlorine": 1.56,
    "Corundum": 2.53,
    "Diamond": 6.07,
    "Distilled Spirits": 4.95,
    "Fluorine": 2.80,
    "Gold": 6.07,
    "Laranite": 28.25,
    "Medical Supply": 18.00,
    "Processed Food": 1.38,
    "Scrap": 1.68,
    "Stims": 3.40,
    "Titanium": 8.27,
    "Tungsten": 3.90,
    "Widdow": 24.00,
}
buying_grim_hex = {
    "Chlorine": 1.44,
    "Flurine": 2.63,
    "Hydrogen": 0.97,
    "Iodine": 0.34
    }

selling_grim_hex = {
    "Altruciatoxine": 11.80,
    "distilled spirits": 4.95,
    "medical suppies": 18.05,
    "processed food": 1.36,
    "stims": 3.40,
    "Widdow": 24.0,
}

#### Sorting the dict into ascending value instead of alphabetical
sort_buying_olisar = sorted(buying_olisar, key=lambda tup: tup[1])
sort_selling_olisar = sorted(selling_olisar, key=lambda tup: (tup[1], tup[0]))
sort_buying_levski = sorted(buying_levski, key=lambda tup: tup[1])
sort_selling_levski = sorted(selling_levski, key=lambda tup: (tup[1], tup[0]))
#sort_buying_grim_hex = sorted(buying_arc_corp_mining_area_157, key=lambda tup: tup[1])
#sort_selling_grim_hex = sorted(selling_arc_corp_mining_area_157, key=lambda tup: (tup[1], tup[0]))

#### picking two dicts (buy/sell) and filtering them to print only common elements.
def common(curr, other):
    return set(curr.keys()).intersection(set(other.keys()))

tradable_items = common(buying_levski, selling_olisar)

#### calculating the prices between possible sales.
prices = {k: selling_olisar[k] - buying_levski[k] for k in tradable_items}

most_profitable_resourse = max(prices.items(), key=operator.itemgetter(1))[0]

#### sorting and printing the most profitable purchase.
profit_ammount = prices
profit_sorted = f"{profit_ammount[most_profitable_resourse]:.2f}"
print(
    f"The most profitable item to buy at {user_purchase_location.title()} is {most_profitable_resourse.title()}\n\
and will make a net profit of {profit_sorted} per unit when sold at {user_sale_destination.title()}"
)
Now it work for me,i have comment out line 78,79 as eg buying_arc_corp_mining_area_157 is not set.

Next time do not post all together working and not working code it can be confusing,
make a working example with eg Dictionary and code that gives problem with Traceback.

Here my test run:
E:\div_code\xy
λ ptpython -i test1.py
# The out from running code
The most profitable item to buy at Mall is Quartz
and will make a net profit of 0.07 per unit when sold at Gold Shop

# Interactive session to test some values 
>>> tradable_items
{'Iodine', 'Aluminum', 'Hydrogen', 'Quartz'}

>>> most_profitable_resourse
'Quartz'

>>> profit_sorted
'0.07'

>>> sort_selling_olisar
['Laranite', 'Scrap', 'Beryl', 'Agricium', 'Chlorine', 'Diamond', 'Distilled Spirits', 'Titanium', 'Aluminum', 'Fluorine', 'Corundum', 'Gold', 'Iodine', 'Processed Food', 'Stims', 'Quartz', 'Tungsten', 'Hydrogen']

>>> sort_buying_levski
['Agricultural Supply', 'Aluminum', 'Iodine', 'Quartz', 'Hydrogen']

>>> prices
{'Iodine': 0.02999999999999997, 'Aluminum': 0.050000000000000044, 'Hydrogen': 0.040000000000000036, 'Quartz': 0.06999999999999984}