Deux codes en public sur le site cocalc.com

Discutez d'informatique ici !
Avatar de l’utilisateur
ortollj
Membre Rationnel
Messages: 554
Enregistré le: 13 Mai 2009, 10:28

deux codes en public sur le site cocalc.com

par ortollj » 15 Fév 2019, 11:35

Bonjour
voici deux de mes codes que j'ai mis en public sur cocalc.com.
peut servir a des debutants. (attention je ne pretends pas que mon codage soit optimal, loin de la ! ) :mrgreen:
cliquer sur le fichier .ipynb --> Open in cocalc --> execute
Hanoi's Towers

Non Transitive Dice
si j'avais su j'aurais pas venu.



Avatar de l’utilisateur
ortollj
Membre Rationnel
Messages: 554
Enregistré le: 13 Mai 2009, 10:28

Re: deux codes en public sur le site cocalc.com

par ortollj » 18 Fév 2019, 12:07

télécharger SageMath pour Windows
https://github.com/sagemath/sage-windows/releases
installez-le (attention l'installation est un peu longuette, occupez vous a autre chose une fois lancée),
ensuite, vous aurez 3 icônes sur votre bureau,
puis cliquez sur celle nommée: sagemath 8.6 notebook,
attendez quelques secondes jusqu'à ce qu'un nouvel onglet du navigateur s'affiche,
puis cliquez sur le bouton en haut à droite nommé "nouveau" dans ce nouvel onglet,
et choisissez " notebook Sagemath8.6" , une nouvel fenetre apparaîtra,
ecrire votre code dans cette nouvelle fenetre, puis cliquez sur le bouton Exécuter:

positionner le chemin de votre dossier de travail qui se trouve ici avec votre nom d'utilisateur:
C:\Program Files\SageMath 8.6\runtime\etc\fstab.d
par exemple mon fichier pour mon dossier IPYNB:
C:\Users\jean-pierre\Documents\SageMath\IPYNB /home/sage ntfs binary,posix=1,user,acl 0 0
(attention !, vous devez quitter SageMath (cad fermer la petite fenetre SageMath8.6 Notebook Server) et le relancer pour que le nouveau chemin soit effectif)

pour utiliser cocalc je trouve qu'il est preferable de construire et debugger
son fichier avec Sagemath, et ensuite sur cocalc.com créé un projet et importer
le fichier .ipynb dans son projet.
si j'avais su j'aurais pas venu.

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 14:00

Re: deux codes en public sur le site cocalc.com

par fatal_error » 20 Fév 2019, 14:07

pour les non transitive dice, on peut peut etre faire un peu plus simple
Code: Tout sélectionner
import numpy as np

def make_die(arr, label):
    return {'v': [np.array(arr)], 'label':label}

def make_multi_die(varr):
    v = []
    l = ''
    for arr in varr:
        v.append(arr['v'][0])
        l = l+arr['label']
    return {'v':v, 'label': l}

def fight(a,b):
    #generate all multi_die throws for a and b in throws_a, throws_b
    def all_throws(*arrays):
        #https://stackoverflow.com/questions/11144513/np-cartesian-product-of-x-and-y-array-points-into-single-array-of-2d-points
        la = len(arrays)
        dtype = np.result_type(*arrays)
        arr = np.empty([len(a) for a in arrays] + [la], dtype=dtype)
        for i, a in enumerate(np.ix_(*arrays)):
            arr[...,i] = a
        return arr.reshape(-1, la)

    throws_a = all_throws(*a['v'])
    throws_b = all_throws(*b['v'])

    #make the cartesian product of throws_a and throws_b and count whenever sum(throw_a) > sum(throw_b). gives p
    s_a = np.sum(throws_a, axis=1)
    s_b = np.sum(throws_b, axis=1)
    s_ab = all_throws(s_a, s_b)

    a_greater_than_b = s_ab[:,0] - s_ab[:,1] > 0
    n_a_greater_than_b = np.sum(a_greater_than_b)
    p = n_a_greater_than_b / len(s_ab)

    print('p(', a['label'], '>', b['label'], ') =', n_a_greater_than_b,'/',len(s_ab), '(',p,')')

if __name__ == '__main__':
    r = make_die([3,3,3,3,3,6],'red')
    g = make_die([1,4,4,4,4,4], 'green')
    w = make_die([2,2,2,5,5,5], 'white')

    #A question
    fight(r,w)
    fight(w,g)
    fight(g,r)

    ##B question
    ww = make_multi_die((w,w))
    rr = make_multi_die((r,r))
    fight(ww,rr)



output:
Code: Tout sélectionner
p( red > white ) = 21 / 36 ( 0.5833333333333334 )
p( white > green ) = 21 / 36 ( 0.5833333333333334 )
p( green > red ) = 25 / 36 ( 0.6944444444444444 )
p( whitewhite > redred ) = 765 / 1296 ( 0.5902777777777778 )
la vie est une fête :)

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 14:00

Re: deux codes en public sur le site cocalc.com

par fatal_error » 20 Fév 2019, 20:04

j'apporte un update parce qu'en fait j'ai pris l'approche un peu bebete (comme d'hab ..) et on peut faire un peu mieux

Code: Tout sélectionner
import numpy as np
import time
import itertools
import math
from collections import Counter
from functools import reduce
def make_die(arr, label):
    return {'v': [np.array(arr)], 'label':label}

def make_multi_die(varr):
    v = []
    l = ''
    for arr in varr:
        v.append(arr['v'][0])
        l = l+arr['label']
    return {'v':v, 'label': l}

def fight(a,b):
    #generate all multi_die throws for a and b in throws_a, throws_b
    def all_throws(*arrays):
        #https://stackoverflow.com/questions/11144513/np-cartesian-product-of-x-and-y-array-points-into-single-array-of-2d-points
        la = len(arrays)
        dtype = np.result_type(*arrays)
        arr = np.empty([len(a) for a in arrays] + [la], dtype=dtype)
        for i, a in enumerate(np.ix_(*arrays)):
            arr[...,i] = a
        return arr.reshape(-1, la)

    throws_a = all_throws(*a['v'])
    throws_b = all_throws(*b['v'])

    #make the cartesian product of throws_a and throws_b and count whenever sum(throw_a) > sum(throw_b). gives p
    s_a = np.sum(throws_a, axis=1)
    s_b = np.sum(throws_b, axis=1)
    s_ab = all_throws(s_a, s_b)

    a_greater_than_b = s_ab[:,0] - s_ab[:,1] > 0
    n_a_greater_than_b = np.sum(a_greater_than_b)
    p = n_a_greater_than_b / len(s_ab)

    print('p(', a['label'], '>', b['label'], ') =', n_a_greater_than_b,'/',len(s_ab), '(',p,')')

def fight_v2(a,b):
    s_a = [math.fsum(throw_a) for throw_a in itertools.product(*a['v'])]
    s_b = [math.fsum(throw_b) for throw_b in itertools.product(*b['v'])]
    a_greater_than_b = [a-b>0 for (a,b) in itertools.product(s_a, s_b)]
    n_a_greater_than_b = np.sum(a_greater_than_b)
    p = n_a_greater_than_b / len(a_greater_than_b)
    print('p(', a['label'], '>', b['label'], ') =', n_a_greater_than_b,'/',len(a_greater_than_b), '(',p,')')


def fight_v3(a,b):
    #handle duplicates
    counters = [Counter(v) for v in (*a['v'], *b['v'])]
    counters_keys = [c.keys() for c in counters]
    l_a = len(a['v'])
    l_b = len(b['v'])

    def aggregate(t):
        beg = t[:l_a]
        end = t[l_b:]

        weight = reduce((lambda x,y:x*y), [counters[i][val] for i, val in enumerate(t)])
        return weight, sum(beg) > sum(end)

    total = 0
    n_a_greater_than_b = 0
    for t in itertools.product(*counters_keys):
        w, gt = aggregate(t)
        total += w
        n_a_greater_than_b += gt * w

    p = n_a_greater_than_b / total
    print('p(', a['label'], '>', b['label'], ') =', n_a_greater_than_b,'/',total, '(',p,')')

if __name__ == '__main__':
    r = make_die([3,3,3,3,3,6],'red')
    g = make_die([1,4,4,4,4,4], 'green')
    w = make_die([2,2,2,5,5,5], 'white')

    #A question
    fight(r,w)
    fight(w,g)
    fight(g,r)

    ##B question
    ww = make_multi_die((w,w,w,w,g))
    rr = make_multi_die((r,r,r,r,g))

    start = time.time()
    fight(ww,rr)
    end = time.time()
    print('elapsed', end - start)

    start = time.time()
    fight_v2(ww,rr)
    end = time.time()
    print('elapsed', end - start)

    start = time.time()
    fight_v3(ww,rr)
    end = time.time()
    print('elapsed', end - start)



output:
Code: Tout sélectionner
p( red > white ) = 21 / 36 ( 0.5833333333333334 )
p( red > white ) = 21 / 36 ( 0.5833333333333334 )
p( white > green ) = 21 / 36 ( 0.5833333333333334 )
p( whitewhitewhitewhitegreen > redredredredgreen ) = 27864000 / 60466176 ( 0.4608196159122085 )
elapsed 1.3132779598236084
p( whitewhitewhitewhitegreen > redredredredgreen ) = 27864000 / 60466176 ( 0.4608196159122085 )
elapsed 7.507621765136719
p( whitewhitewhitewhitegreen > redredredredgreen ) = 27864000 / 60466176 ( 0.4608196159122085 )
elapsed 0.011631488800048828



Dans fight_v2, c'est pareil, sauf que j'ai lu que itertools.product c'était censé etre mieux que numpy SI on itère et comme on itère... je voulais voir ce que ca donne..

Dans fight_v3, on est un poil plus malin, et on evite de gérer les doublons et on pondère directement genre "arbre" de proba

ce qu'on voit c'est que itertools pas si fantastique que ça (mais j'ai surement dit faire de la mm)
la vie est une fête :)

Avatar de l’utilisateur
ortollj
Membre Rationnel
Messages: 554
Enregistré le: 13 Mai 2009, 10:28

Re: deux codes en public sur le site cocalc.com

par ortollj » 21 Fév 2019, 07:26

Bonjour fatal_error
c'est du Python 3 ?

mon probleme c'est que j'ai appris le Python sur le tas, en realisant des petits programmes.
l'avantage c'est qu'on peut vite apprendre les bases mais l'inconvenient c'est que j'ai des lacunes.
par exemple je ne connaissais pas l'utilisation de * ( apart pour multiplier :mrgreen: )

Code: Tout sélectionner
The single star * unpacks the sequence/collection into positional arguments, so you can do this:
def sum(a, b):
    return a + b

values = (1, 2)

s = sum(*values)
This will unpack the tuple so that it actually executes as:
s = sum(1, 2)


What does the star operator mean?

il va falloir je pense que je prenne un cours de Python :rouge:
si j'avais su j'aurais pas venu.

Avatar de l’utilisateur
fatal_error
Modérateur
Messages: 6610
Enregistré le: 22 Nov 2007, 14:00

Re: deux codes en public sur le site cocalc.com

par fatal_error » 21 Fév 2019, 18:07

salut ortollj,

> c'est du Python 3 ?
oui, la version précise je sais pas, mais ca tourne avec python3.5
la vie est une fête :)

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 2 invités

Tu pars déja ?



Fais toi aider gratuitement sur Maths-forum !

Créé un compte en 1 minute et pose ta question dans le forum ;-)
Inscription gratuite

Identification

Pas encore inscrit ?

Ou identifiez-vous :

Inscription gratuite