NoPaste

garten-additiv.py

von chrbr
SNIPPET_DESC:
garten-additiv.py
SNIPPET_CREATION_TIME:
07.04.2023 02:21:08
SNIPPET_PRUNE_TIME:
Unendlich

SNIPPET_TEXT:
  1. #!/usr/bin/env python3
  2.  
  3. #======================================================================
  4. # Basierend auf der Arbeit von Huo
  5. # Der Graphentheorethische Teil ist per Hand gemacht.
  6. # Beginnend mit der Hauptpflanze werden zusätzliche Pflanzen
  7. # hinzu gefügt. Bei Unverträglichkeit wird diese Gruppe verworfen.
  8. # Ansonsten wird weiter gemacht bis man in keiner der Gruppen noch
  9. # eine Pflanze hinzufügen kann.
  10. #
  11. # Gute und schlechte Pflanzennachbarn müssen in zwei getrennten csv-Dateien
  12. # friends.csv und enemies.csv
  13. # in der Form PFLANZE1,PFLANZE2 hinterlegt sein (ein Paar pro Zeile)
  14. #
  15. # Die Pfade in den Zeilen 24 und 25 sind bei Bedarf anzupassen!
  16. #
  17. # Aufruf:
  18. #     garten_dazu.py HAUPTPFLANZE
  19. # wobei HAUPTPFLANZE ein einzelner Name aus der Datei friends.csv ist
  20. #======================================================================
  21.  
  22. import csv
  23. import itertools
  24. import os
  25. import sys
  26.  
  27. # Einlesen der beiden csv-Dateien (Pfade bei Bedarf anpassen!) als Listen zwei-elementiger Mengen
  28. friends = list(set(line) for line in csv.reader(open(os.path.expanduser("./friends.csv"))))
  29. enemies = list(set(line) for line in csv.reader(open(os.path.expanduser("./enemies.csv"))))
  30.  
  31. # Plausibilitätsprüfung der Listen auf widersprüchliche Nachbarbeziehungen
  32. if [s for s in friends if s in enemies] != []:
  33.     print("Pflanzenpaar darf nicht zugleich in friends.csv und enemies.csv liegen")
  34.     print("Dubletten:", [s for s in friends if s in enemies])
  35.     sys.exit(1)
  36.  
  37. # Check Parameter
  38. if not [i for i in friends if sys.argv[-1] in i] or len(sys.argv) != 2:
  39.     print("Script muss mit einer Einzelpflanze aus friends.csv als einzigem Parameter aufgerufen werden!")
  40.     sys.exit(1)    # Abbruch bei Aufruf ohne Parameter oder mit falschem Parameter
  41.  
  42. hauptpflanze = sys.argv[1]
  43.  
  44. # Gute Nachbarn der Hauptpflanze (Liste der Paare {Hauptpflanze, Guter Nachbar})
  45. friends_h = list(s for s in friends if hauptpflanze in s)
  46.  
  47. # Menge der guten Nachbarn der Hauptpflanze
  48. fh = set().union(*friends_h)
  49.  
  50. # Kombinationen dieser guten Nachbarn als Liste zwei-elementiger Mengen
  51. fc = list(set(s) for s in itertools.combinations(fh, 2))
  52.  
  53. # darunter schlechte Nachbarn
  54. enemies_c = list(sorted(s) for s in fc if s in enemies)
  55.  
  56. # Typen
  57. # friends   <class 'list'>
  58. # enemies   <class 'list'> of set  as pair of fruits
  59. # enemies_c <class 'list'> of list as pair of fruits
  60. # friends_h <class 'list'>
  61. # fc        <class 'list'>
  62. # fh        <class 'set'>
  63.  
  64. # print("friends", type(friends))
  65. # print("enemies", type(enemies))
  66. # print("enemies_c", type(enemies_c))
  67. # print("friends_h", type(friends_h))
  68. # print("fc", type(fc))
  69. # print("fh", type(fh))
  70.  
  71. # Ausgabe der Guten Nachbarn der Hauptpflanze
  72. print ("-------------------------------------")
  73. print ("Gute Nachbarn von", hauptpflanze, ":")
  74. fh_d = fh
  75. fh_d.discard(hauptpflanze)
  76. print (*sorted(fh_d), sep=", ")
  77. print ()
  78.  
  79. # Ausgabe der Paare schlechter Nachbarn:
  80. print ("Darunter harmonieren nicht:")
  81. print (*sorted(enemies_c), sep="\n")
  82. print ()
  83. # Zuerst wird eine sortierte Liste der Freunde der Hauptpflanze erzeugt.
  84. # Die wird in den Iterationen verwendet zum probeweisen Hinzufügen
  85. # von Pflanzen zu existierenden Gruppen.
  86. lfriends = sorted(list(fh))
  87. # sgroups sind die Eingangsgruppen in jeden Itrationsschritt.
  88. # Es wird für alle Elemente von lfriennds versucht, sie den
  89. # einzelnen Gruppen hinzuzufügen. NICHT: Dabei wird in lfriends nur nach rechts
  90. # von der hinzuzufügenden Pflanze gesucht. Die Kombinationen nach links wurden
  91. # implizit schon abgearbeitet und würden nur als Dubletten auftauchen.
  92. sgroups =  set()
  93.  
  94. for friend in lfriends:
  95.      sgroups.add(frozenset([friend]))
  96. skandidat = frozenset(lfriends)
  97. lfinal = []
  98. etwas_erweiterbar = True
  99. while etwas_erweiterbar:
  100.     snext = set()
  101.     etwas_erweiterbar = False
  102.     for group in sgroups:
  103.         erweitert = False
  104.         for kandidat in skandidat-group:
  105.             vertraeglich = True
  106.             for pflanze in group:
  107.                 vertraeglich = vertraeglich and set([kandidat, pflanze]) not in enemies
  108.             if vertraeglich:
  109.                 erweitert = True
  110.                 etwas_erweiterbar = True
  111.                 tmp = set(group)
  112.                 tmp.add(kandidat)
  113.                 snext.add(frozenset(tmp))
  114.         if not erweitert:
  115.             ltmp = list(group.copy())
  116.             ltmp.append(hauptpflanze)
  117.             lfinal.append(sorted(ltmp))
  118.     sgroups = snext.copy()
  119. # Ausgabe der Mischkulturen (sortiert nach Größe)
  120. print ("Mögliche Mischkulturen:")
  121. print(*sorted(lfinal, key=len), sep='\n')

Quellcode

Hier kannst du den Code kopieren und ihn in deinen bevorzugten Editor einfügen. PASTEBIN_DOWNLOAD_SNIPPET_EXPLAIN