Re: [Tutor] Accessing a tuple of a dictionary's value

2018-08-24 Thread Mats Wichmann
On 08/24/2018 03:02 AM, Alan Gauld via Tutor wrote:
> CCing list, please always use Reply-All or Reply-List when responding
> to the tutor list so that everyone gets a chance to reply.
> 
> 
> On 24/08/18 00:35, Roger Lea Scherer wrote:
>>
>> Lots of code missing, but the line I'm interested in is this:
>> print("Your number  " + str(numerator) + "/" + str(denominator) + " 
>> is approximately  " + str(fractions[ranges[i][0]][0]) + "/" +
>> str(fractions[ranges[i][0]][1]))
>> I get this output:
>> Your number  37/112  is approximately  1/3
>>
>> From this line:
>> print("Your number ",  numerator, "/",  denominator, " is
>> approximately ", fractions[ranges[i][0]][0], "/",
>> fractions[ranges[i][0]][1])
>> I get this output:
>> Your number  37 / 112  is approximately  1 / 3
>>
>> I'm being picky. I don't like the spaces between the 37 and 112 and 1
>> and 3...
> 
>> my question is: Is there another way other than these two to
>> print without all the str nonsense and not get the spaces
> 
> Yes, use string formatting. 

In addition, let's understand what is happening above.


print("Your number ",  numerator, "/",  denominator, " is approximately
", fractions[ranges[i][0]][0], "/", fractions[ranges[i][0]][1])

You are doing two things in this line
1. construct a string
2. print the string

The constructed string is never assigned a name, so it is not saved
after the print function is done with it (no more references), but
that's what is happening. In constructing the string, there are about a
zillion options, in this case it is "adding" smaller string pieces together.

Try:

s = "hello" + "world"
print(s)

no spaces :)

the string class provides a "+" operator which is just concatenation.
So when building up a new string this way, put spaces in if you want
them, and don't put spaces in if you don't.   If your intent it to
nicely format a string for visual display on your terminal or to a file,
then string concatenation is a more cumbersome route than tools which
are designed for the purpose, but there are plenty of good uses for it
as well.

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Accessing a tuple of a dictionary's value

2018-08-24 Thread Alan Gauld via Tutor
On 24/08/18 10:02, Alan Gauld via Tutor wrote:
> CCing list, please always use Reply-All or Reply-List when responding
> to the tutor list so that everyone gets a chance to reply.
> 
> 
> On 24/08/18 00:35, Roger Lea Scherer wrote:
>>
>> Lots of code missing, but the line I'm interested in is this:
>> print("Your number  " + str(numerator) + "/" + str(denominator) + " 
>> is approximately  " + str(fractions[ranges[i][0]][0]) + "/" +
>> str(fractions[ranges[i][0]][1]))
>> I get this output:
>> Your number  37/112  is approximately  1/3
>>

> print("Your number  %d/%d is approximately %d/%d" % (numerator,
>  denominator,
> fractions[ranges[i][0]][0],
> fractions[ranges[i][0]][1]))
> 
> The stacked layout is of course optional, I just think it looks clearer.

It would look clearer if the mail hadn't messed it up! :-)
The two fractions() lines were intended to be under the
numerator,denominator values not on the left side!

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Accessing a tuple of a dictionary's value

2018-08-24 Thread Alan Gauld via Tutor
CCing list, please always use Reply-All or Reply-List when responding
to the tutor list so that everyone gets a chance to reply.


On 24/08/18 00:35, Roger Lea Scherer wrote:
>
> Lots of code missing, but the line I'm interested in is this:
> print("Your number  " + str(numerator) + "/" + str(denominator) + " 
> is approximately  " + str(fractions[ranges[i][0]][0]) + "/" +
> str(fractions[ranges[i][0]][1]))
> I get this output:
> Your number  37/112  is approximately  1/3
>
> From this line:
> print("Your number ",  numerator, "/",  denominator, " is
> approximately ", fractions[ranges[i][0]][0], "/",
> fractions[ranges[i][0]][1])
> I get this output:
> Your number  37 / 112  is approximately  1 / 3
>
> I'm being picky. I don't like the spaces between the 37 and 112 and 1
> and 3...

> my question is: Is there another way other than these two to
> print without all the str nonsense and not get the spaces

Yes, use string formatting. It gives you much more control over the
content of your string including field width, number of decimal places,
justification, etc.

For example in your case:


print("Your number  %d/%d is approximately %d/%d" % (numerator,
 denominator,

fractions[ranges[i][0]][0],

fractions[ranges[i][0]][1]))

The stacked layout is of course optional, I just think it looks clearer.

See the thread on TimesTable for more on formatting and look at
the documentation :

https://docs.python.org/3/library/stdtypes.html#old-string-formatting
and
https://docs.python.org/3/library/string.html#formatstrings

Use whichever style you prefer.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Accessing a tuple of a dictionary's value

2018-08-22 Thread Alan Gauld via Tutor
On 22/08/18 17:27, Mats Wichmann wrote:

> I'm really unfond of accessing members of a collection by numeric index.
> 
>   >>> numer, denom = d["twothirds"]
>   >>> print(numer, denom)
>   (2, 3)
> 
> I think that's nicer than:  numer = d["twothirds][0]

You can alsao avoid indexes with the namedtuple
class in the collections module:

>>> import collections as coll
>>> frac = coll.namedtuple("Fraction", ['num','den'])
>>> frac

>>> f = frac(2,3)
>>> f.num
2
>>> f.den
3
>>> fracs = {0.67:f}
>>> fracs[0.67].num
2
>>>

Or just use a nested dictionary:

fracs = {0.67, {'num':2, 'den':3}}

print( fracs[0.67]['num'] )

But you have the inconvenience of quoting the
field names.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Accessing a tuple of a dictionary's value

2018-08-22 Thread Mats Wichmann
On 08/21/2018 04:27 PM, Roger Lea Scherer wrote:
> So I'm trying to divide fractions, technically I suppose integers. So, for
> instance, when the user inputs a 1 as the numerator and a 2 as the
> denominator to get the float 0.5, I want to put the 0.5 as the key in a
> dictionary and the 1 and the 2 as the values of the key in a list {0.5: [1,
> 2]}, hoping to access the 1 and 2 later, but not together. I chose a
> dictionary so the keys won't duplicate.

...
> Both of these errors sort of make sense to me, but I can't find a way to
> access the 1 or the 2 in the dictionary key:value pair {0.5: [1, 2]}

To add a little bit to the discussion that has already taken place:

I'm really unfond of accessing members of a collection by numeric index.
Perhaps unreasonably so! It always makes you stop and think when you
swing back and look at code later. foo[1]? what was that second element
again?

Fortunately, Python will let you "unpack" a tuple or list at assignment
time, where you provide a number of variables on the left hand side that
is equal to the length of the tuple on the right hand side.

Setting aside the floating point consideration here by using a string
instead, let's say we have a dictionary with two keys, which have a
value which is a tuple as you've described it, numerator and demoninator:

  >>> d = {"half": (1, 2), "twothirds": (2, 3)}

you fetch the value by indexing by key, like d["twothirds"]

when doing so, you can immediately assign the value to variables that
have meaning to you, like this:

  >>> numer, denom = d["twothirds"]
  >>> print(numer, denom)
  (2, 3)

I think that's nicer than:  numer = d["twothirds][0]
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Accessing a tuple of a dictionary's value

2018-08-22 Thread Steven D'Aprano
On Tue, Aug 21, 2018 at 03:27:46PM -0700, Roger Lea Scherer wrote:

> I want to put the 0.5 as the key in a
> dictionary and the 1 and the 2 as the values of the key in a list {0.5: [1,
> 2]}, hoping to access the 1 and 2 later, but not together.

Let's do some experimentation. Here's a list:

py> L = [11, 23]
py> print(L[0])  # get the first item
11
py> print(L[1])  # get the second item
23

(Yes, I know that its funny that Python counts from 0, so the second 
item is at index 1...)

That syntax works no matter where the list L comes from. Let's put it in 
a dict:

py> D = {11/23: [11, 23]}
py> print(D)
{0.4782608695652174: [11, 23]}


Now let's try retrieving it:

py> print(D[11/23])
[11, 23]

So where we said "L" before, we can say "D[11/23]" now:

py> print(L[1])
23
py> print(D[11/23][1])
23


But if you're going to do this, I think fractions are nicer.


py> from fractions import Fraction
py> x = Fraction(11, 23)
py> x.numerator
11
py> x.denominator
23
py> float(x)
0.4782608695652174




-- 
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Accessing a tuple of a dictionary's value

2018-08-22 Thread Steven D'Aprano
On Tue, Aug 21, 2018 at 03:27:46PM -0700, Roger Lea Scherer wrote:

> So I'm trying to divide fractions, technically I suppose integers.

Python has a library for doing maths with fractions. Unfortunately it is 
considerably too complex to use as a learning example, but as a 
practical library for use, it's great.

py> from fractions import Fraction
py> a = Fraction(7, 9)
py> a * 3
Fraction(7, 3)
py> a + 2
Fraction(25, 9)
py> a - Fraction(1, 9)
Fraction(2, 3)


> So, for
> instance, when the user inputs a 1 as the numerator and a 2 as the
> denominator to get the float 0.5, I want to put the 0.5 as the key in a
> dictionary 

Be careful. Floats are quirky:

py> Fraction(1, 3)
Fraction(1, 3)

but converting from a float reveals something strange:

py> Fraction(1/3)
Fraction(6004799503160661, 18014398509481984)

The problem is that the float generated by 1/3 is *not* equal to the 
mathematical fraction 1 over 3. Computer floats have only a finite 
precision, in the case of Python 64 bits. Fractions which are repeating 
in binary cannot be represented as an exact float.

So the mathematically precise number 1/3 looks like this is decimal:

0....  # need an infinite number of 3s

and like this in binary (base two):

0.01010101...  # need an infinite number of 01s

Since that would take an infinite amount of memory, it is impossible to 
store 1/3 as a floating point number. The closest we get in Python is 

0.01010101010101010101010101010101010101010101010101 (binary)

which is precisely and exactly equal to 

6004799503160661/18014398509481984

rather than 1/3.

The bottom line is this: if you try working with floats in this way, 
you're likely to get surprised from time to time. See here for more 
detail:

https://docs.python.org/3/faq/design.html#why-are-floating-point-calculations-so-inaccurate

More to follow in a second response.



-- 
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Accessing a tuple of a dictionary's value

2018-08-22 Thread Alan Gauld via Tutor
On 21/08/18 23:27, Roger Lea Scherer wrote:

> I can't find anything in StackOverflow or Python documentation specifically
> about this. They talk about accessing a list or a tuple or a dictionary,
> but not when the value is a tuple or list.

The value is irrelevant youi access the value in
exactly the same way  regardless of data:

data = dictionary[key]

Now you can access data's elements as normal

print(data[0])

Of course you can combine those into a single line:

print(dictionary[key][0])

> fractions.values([0])
> which gives a TypeError: values() takes no arguments (1 given)

values returns a list(*) of all the values in your dict.
In your case a list of tuples. But because it returns
all of them it requires no arguments.

(*)Not strictly a list, but the v3 implementation of this
is a bit weird so we'll ignore the niceties for now!

> fractions.values()[0]
> which gives a TypeError: 'dict_values' object does not support indexing

As per the note it doesn't return a real list
(although you can convert it) but that doesn't matter
since even if what you are trying worked it would return
the first tuple, not the first integer of the tuple.

> Both of these errors sort of make sense to me, but I can't find a way to
> access the 1 or the 2 in the dictionary key:value pair {0.5: [1, 2]}

values[0.5][0]

However remember that floats are not exact representations
so if you use a calculated value as your key it may not exactly
match your given key and it won't find the item!

>>> d = {}
>>> d[0.3] = (3,10)
>>> d[0.3]
(3, 10)
>>> d[0.1+0.2]
Traceback (most recent call last):
  File "", line 1, in 
d[0.1+0.2]
KeyError: 0.30004
>>>
>>> d[ round(0.1+0.2, 2) ]
(3, 10)
>>>

Just something to be aware of.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor