From dc5ec6a1d2decd55f9a034b3b84286e9bd509a74 Mon Sep 17 00:00:00 2001 From: Evan Pratten Date: Mon, 15 Jul 2019 19:06:57 -0400 Subject: [PATCH] mindmap --- _posts/2019-07-15-MindMap.md | 128 ++++++++++++ _site/all_posts.html | 7 + _site/assets/images/mindmap-simple.png | Bin 0 -> 25758 bytes _site/blog/2019/07/15/mindmap.html | 264 +++++++++++++++++++++++++ _site/feed.xml | 129 ++++++++++-- _site/index.html | 4 +- assets/images/mindmap-simple.png | Bin 0 -> 25758 bytes 7 files changed, 517 insertions(+), 15 deletions(-) create mode 100644 _posts/2019-07-15-MindMap.md create mode 100644 _site/assets/images/mindmap-simple.png create mode 100644 _site/blog/2019/07/15/mindmap.html create mode 100644 assets/images/mindmap-simple.png diff --git a/_posts/2019-07-15-MindMap.md b/_posts/2019-07-15-MindMap.md new file mode 100644 index 0000000..841cd98 --- /dev/null +++ b/_posts/2019-07-15-MindMap.md @@ -0,0 +1,128 @@ +--- +layout: post +title: "Mind map generation with Python" +description: "Step 1" +date: 2019-07-15 18:38:00 +categories: projects frc +--- + +While working on an assignment with [Coggle](https://coggle.it) today, I noticed an interesting option in the save menu. *Download as .mm file*. Having rarely worked with mind maps before, and only doing it online, it never occured to me that someone would have a file format for it. So I took a look. + +## What is a .mm file? +It turns out, a `.mm` file is just some XML describing the mind map. Here is a simple mind map: + +![Simple Mind Map](/assets/images/mindmap-simple.png) + +And again as a `.mm` file: + +```xml + + + + + + + + + + + + + + + + + + +``` + +Neat, right? + +## What can we do with it? +I have not done much research about this because I wanted to work all of this out on my own. But I know one thing as a fact: working with XML sucks (especially in Python). I decided that this would be much better if I could load `.mm` files as JSON. This would allow easy manipulation and some cool projects. + +## My script +Like everything I do, I made a script to play with these files. + +It's pretty simple. First, It loads a `.mm` file, then parses it into a `list` of `xml.etree.ElementTree.Element`. + +```python +raw_mm = "" + +with open(args.file, "r") as fp: + raw_mm = fp.read() + fp.close() + +xml = ET.fromstring(raw_mm) +``` + +The parsed `list` is then passed into a recursive function that constructs a `dict` + +```python +def xmlToDict(xml): + output = [] + for elem in list(xml): + + if "TEXT" not in elem.attrib: + continue + + name = elem.attrib['TEXT'] + json_element = {"name": name} + + try: + json_element["children"] = xmlToDict(elem) + except: + continue + + # Detect node type + if json_element["children"]: + json_element["type"] = "branch" + else: + json_element["type"] = "leaf" + del json_element["children"] + + output.append(json_element) + + return output +``` + +Finally, the `dict` is written to a file with `json.dump` + +```python +json.dump(mind_map, open(args.file + ".json", "w")) +``` + +The whole script (with comments) can be found on my [GitHub account](https://gist.github.com/Ewpratten/0d8f7c7371380c9ca8adcfc6502ccf84#file-parser-py). + +## The output +Running the `.mm` file from above through the script gives: + +```json +[ + { + "name":"Master Node", + "children":[ + { + "name":"Child branch", + "children":[ + { + "name":"Children 1", + "type":"leaf" + }, + { + "name":"Children 2", + "type":"leaf" + } + ], + "type":"branch" + } + ], + "type":"branch" + } +] +``` + +## The next step +This script just translates a `.mm` file to JSON. Nothing else. Next, I want to convert this to a library, and add a JSON to `.mm` function as well. This leads into my ultimate goal for this project. + +I want a script that I can drop in the root of any project to build a [Gource](https://gource.io/)-style visualization of the folder structure. This will give me a way to make cool visualizations for lessons on the robotics team. \ No newline at end of file diff --git a/_site/all_posts.html b/_site/all_posts.html index bc791df..bd61e67 100644 --- a/_site/all_posts.html +++ b/_site/all_posts.html @@ -96,6 +96,13 @@
    + +
  • Mind map generation with Python

  • + + + + +
  • Taking a look back at GMAD

  • diff --git a/_site/assets/images/mindmap-simple.png b/_site/assets/images/mindmap-simple.png new file mode 100644 index 0000000000000000000000000000000000000000..44565fe642709f6a74b71c463138da75bb2334aa GIT binary patch literal 25758 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 u1W?N>*n?SnW + + + + Evan Pratten + + + + + + + + + + + + + + + +
    + + + + + + + + + + + +
    + + +
    +
    + +

    While working on an assignment with Coggle today, I noticed an interesting option in the save menu. Download as .mm file. Having rarely worked with mind maps before, and only doing it online, it never occured to me that someone would have a file format for it. So I took a look.

    + +

    What is a .mm file?

    +

    It turns out, a .mm file is just some XML describing the mind map. Here is a simple mind map:

    + +

    Simple Mind Map

    + +

    And again as a .mm file:

    + +
    <map version="0.9.0">
    +    <node TEXT="Master Node" FOLDED="false" POSITION="right" ID="5d2d02b1a315dd0879f48c1c" X_COGGLE_POSX="0" X_COGGLE_POSY="0">
    +        <edge COLOR="#b4b4b4"/>
    +        <font NAME="Helvetica" SIZE="17"/>
    +        <node TEXT="Child branch" FOLDED="false" POSITION="right" ID="f72704969525d2a0333dd635">
    +            <edge COLOR="#7aa3e5"/>
    +            <font NAME="Helvetica" SIZE="15"/>
    +            <node TEXT="Children 1" FOLDED="false" POSITION="right" ID="c83826af506cae6e55761d5c">
    +                <edge COLOR="#7ea7e5"/>
    +                <font NAME="Helvetica" SIZE="13"/>
    +            </node>
    +            <node TEXT="Children 2" FOLDED="false" POSITION="right" ID="47723a4d0fb766863f70d204">
    +                <edge COLOR="#82aae7"/>
    +                <font NAME="Helvetica" SIZE="13"/>
    +            </node>
    +        </node>
    +    </node>
    +</map>
    +
    + +

    Neat, right?

    + +

    What can we do with it?

    +

    I have not done much research about this because I wanted to work all of this out on my own. But I know one thing as a fact: working with XML sucks (especially in Python). I decided that this would be much better if I could load .mm files as JSON. This would allow easy manipulation and some cool projects.

    + +

    My script

    +

    Like everything I do, I made a script to play with these files.

    + +

    It’s pretty simple. First, It loads a .mm file, then parses it into a list of xml.etree.ElementTree.Element.

    + +
    raw_mm = ""
    +
    +with open(args.file, "r") as fp:
    +    raw_mm = fp.read()
    +    fp.close()
    +
    +xml = ET.fromstring(raw_mm)
    +
    + +

    The parsed list is then passed into a recursive function that constructs a dict

    + +
    def xmlToDict(xml):
    +    output = []
    +    for elem in list(xml):
    +
    +        if "TEXT" not in elem.attrib:
    +            continue
    +        
    +        name = elem.attrib['TEXT']
    +        json_element = {"name": name}
    +
    +        try:            
    +            json_element["children"] = xmlToDict(elem)
    +        except:
    +            continue
    +        
    +        # Detect node type
    +        if json_element["children"]:
    +            json_element["type"] = "branch"
    +        else:
    +            json_element["type"] = "leaf"
    +            del json_element["children"]
    +        
    +        output.append(json_element)
    +    
    +    return output
    +
    + +

    Finally, the dict is written to a file with json.dump

    + +
    json.dump(mind_map, open(args.file + ".json", "w"))
    +
    + +

    The whole script (with comments) can be found on my GitHub account.

    + +

    The output

    +

    Running the .mm file from above through the script gives:

    + +
    [
    +    {
    +        "name":"Master Node",
    +        "children":[
    +            {
    +                "name":"Child branch",
    +                "children":[
    +                    {
    +                        "name":"Children 1",
    +                        "type":"leaf"
    +                    },
    +                    {
    +                        "name":"Children 2",
    +                        "type":"leaf"
    +                    }
    +                ],
    +                "type":"branch"
    +            }
    +        ],
    +        "type":"branch"
    +    }
    +]
    +
    + +

    The next step

    +

    This script just translates a .mm file to JSON. Nothing else. Next, I want to convert this to a library, and add a JSON to .mm function as well. This leads into my ultimate goal for this project.

    + +

    I want a script that I can drop in the root of any project to build a Gource-style visualization of the folder structure. This will give me a way to make cool visualizations for lessons on the robotics team.

    +

    +
    +
    + +
    + + + + +
    + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/_site/feed.xml b/_site/feed.xml index 7052881..cab9c7b 100644 --- a/_site/feed.xml +++ b/_site/feed.xml @@ -1,4 +1,118 @@ -Jekyll2019-07-15T11:11:19-04:00http://0.0.0.0:4000/feed.xmlEvan PrattenComputer wizard, student, <a href="https://github.com/frc5024">@frc5024</a> programming team lead, and radio enthusiast.Taking a look back at GMAD2019-07-13T10:43:00-04:002019-07-13T10:43:00-04:00http://0.0.0.0:4000/blog/2019/07/13/Lookback-GMAD<p>One day, back in June of 2018, I was both looking for a new project to work on, and trying to decide which Linux distro to install on one of my computers. From this, a little project was born. <a href="/gmad">Give Me a Distro</a> (or, GMAD, as I like to call it) is a little website that chooses a random distribution of Linux and shows a description of what you are about to get yourself into, and a download link for the latest ISO.</p> +Jekyll2019-07-15T19:01:28-04:00http://0.0.0.0:4000/feed.xmlEvan PrattenComputer wizard, student, <a href="https://github.com/frc5024">@frc5024</a> programming team lead, and radio enthusiast.Mind map generation with Python2019-07-15T14:38:00-04:002019-07-15T14:38:00-04:00http://0.0.0.0:4000/blog/2019/07/15/MindMap<p>While working on an assignment with <a href="https://coggle.it">Coggle</a> today, I noticed an interesting option in the save menu. <em>Download as .mm file</em>. Having rarely worked with mind maps before, and only doing it online, it never occured to me that someone would have a file format for it. So I took a look.</p> + +<h2 id="what-is-a-mm-file">What is a .mm file?</h2> +<p>It turns out, a <code class="highlighter-rouge">.mm</code> file is just some XML describing the mind map. Here is a simple mind map:</p> + +<p><img src="/assets/images/mindmap-simple.png" alt="Simple Mind Map" /></p> + +<p>And again as a <code class="highlighter-rouge">.mm</code> file:</p> + +<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;map</span> <span class="na">version=</span><span class="s">"0.9.0"</span><span class="nt">&gt;</span> + <span class="nt">&lt;node</span> <span class="na">TEXT=</span><span class="s">"Master Node"</span> <span class="na">FOLDED=</span><span class="s">"false"</span> <span class="na">POSITION=</span><span class="s">"right"</span> <span class="na">ID=</span><span class="s">"5d2d02b1a315dd0879f48c1c"</span> <span class="na">X_COGGLE_POSX=</span><span class="s">"0"</span> <span class="na">X_COGGLE_POSY=</span><span class="s">"0"</span><span class="nt">&gt;</span> + <span class="nt">&lt;edge</span> <span class="na">COLOR=</span><span class="s">"#b4b4b4"</span><span class="nt">/&gt;</span> + <span class="nt">&lt;font</span> <span class="na">NAME=</span><span class="s">"Helvetica"</span> <span class="na">SIZE=</span><span class="s">"17"</span><span class="nt">/&gt;</span> + <span class="nt">&lt;node</span> <span class="na">TEXT=</span><span class="s">"Child branch"</span> <span class="na">FOLDED=</span><span class="s">"false"</span> <span class="na">POSITION=</span><span class="s">"right"</span> <span class="na">ID=</span><span class="s">"f72704969525d2a0333dd635"</span><span class="nt">&gt;</span> + <span class="nt">&lt;edge</span> <span class="na">COLOR=</span><span class="s">"#7aa3e5"</span><span class="nt">/&gt;</span> + <span class="nt">&lt;font</span> <span class="na">NAME=</span><span class="s">"Helvetica"</span> <span class="na">SIZE=</span><span class="s">"15"</span><span class="nt">/&gt;</span> + <span class="nt">&lt;node</span> <span class="na">TEXT=</span><span class="s">"Children 1"</span> <span class="na">FOLDED=</span><span class="s">"false"</span> <span class="na">POSITION=</span><span class="s">"right"</span> <span class="na">ID=</span><span class="s">"c83826af506cae6e55761d5c"</span><span class="nt">&gt;</span> + <span class="nt">&lt;edge</span> <span class="na">COLOR=</span><span class="s">"#7ea7e5"</span><span class="nt">/&gt;</span> + <span class="nt">&lt;font</span> <span class="na">NAME=</span><span class="s">"Helvetica"</span> <span class="na">SIZE=</span><span class="s">"13"</span><span class="nt">/&gt;</span> + <span class="nt">&lt;/node&gt;</span> + <span class="nt">&lt;node</span> <span class="na">TEXT=</span><span class="s">"Children 2"</span> <span class="na">FOLDED=</span><span class="s">"false"</span> <span class="na">POSITION=</span><span class="s">"right"</span> <span class="na">ID=</span><span class="s">"47723a4d0fb766863f70d204"</span><span class="nt">&gt;</span> + <span class="nt">&lt;edge</span> <span class="na">COLOR=</span><span class="s">"#82aae7"</span><span class="nt">/&gt;</span> + <span class="nt">&lt;font</span> <span class="na">NAME=</span><span class="s">"Helvetica"</span> <span class="na">SIZE=</span><span class="s">"13"</span><span class="nt">/&gt;</span> + <span class="nt">&lt;/node&gt;</span> + <span class="nt">&lt;/node&gt;</span> + <span class="nt">&lt;/node&gt;</span> +<span class="nt">&lt;/map&gt;</span> +</code></pre></div></div> + +<p>Neat, right?</p> + +<h2 id="what-can-we-do-with-it">What can we do with it?</h2> +<p>I have not done much research about this because I wanted to work all of this out on my own. But I know one thing as a fact: working with XML sucks (especially in Python). I decided that this would be much better if I could load <code class="highlighter-rouge">.mm</code> files as JSON. This would allow easy manipulation and some cool projects.</p> + +<h2 id="my-script">My script</h2> +<p>Like everything I do, I made a script to play with these files.</p> + +<p>It’s pretty simple. First, It loads a <code class="highlighter-rouge">.mm</code> file, then parses it into a <code class="highlighter-rouge">list</code> of <code class="highlighter-rouge">xml.etree.ElementTree.Element</code>.</p> + +<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">raw_mm</span> <span class="o">=</span> <span class="s">""</span> + +<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="nb">file</span><span class="p">,</span> <span class="s">"r"</span><span class="p">)</span> <span class="k">as</span> <span class="n">fp</span><span class="p">:</span> + <span class="n">raw_mm</span> <span class="o">=</span> <span class="n">fp</span><span class="o">.</span><span class="n">read</span><span class="p">()</span> + <span class="n">fp</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> + +<span class="n">xml</span> <span class="o">=</span> <span class="n">ET</span><span class="o">.</span><span class="n">fromstring</span><span class="p">(</span><span class="n">raw_mm</span><span class="p">)</span> +</code></pre></div></div> + +<p>The parsed <code class="highlighter-rouge">list</code> is then passed into a recursive function that constructs a <code class="highlighter-rouge">dict</code></p> + +<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">xmlToDict</span><span class="p">(</span><span class="n">xml</span><span class="p">):</span> + <span class="n">output</span> <span class="o">=</span> <span class="p">[]</span> + <span class="k">for</span> <span class="n">elem</span> <span class="ow">in</span> <span class="nb">list</span><span class="p">(</span><span class="n">xml</span><span class="p">):</span> + + <span class="k">if</span> <span class="s">"TEXT"</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">elem</span><span class="o">.</span><span class="n">attrib</span><span class="p">:</span> + <span class="k">continue</span> + + <span class="n">name</span> <span class="o">=</span> <span class="n">elem</span><span class="o">.</span><span class="n">attrib</span><span class="p">[</span><span class="s">'TEXT'</span><span class="p">]</span> + <span class="n">json_element</span> <span class="o">=</span> <span class="p">{</span><span class="s">"name"</span><span class="p">:</span> <span class="n">name</span><span class="p">}</span> + + <span class="k">try</span><span class="p">:</span> + <span class="n">json_element</span><span class="p">[</span><span class="s">"children"</span><span class="p">]</span> <span class="o">=</span> <span class="n">xmlToDict</span><span class="p">(</span><span class="n">elem</span><span class="p">)</span> + <span class="k">except</span><span class="p">:</span> + <span class="k">continue</span> + + <span class="c1"># Detect node type +</span> <span class="k">if</span> <span class="n">json_element</span><span class="p">[</span><span class="s">"children"</span><span class="p">]:</span> + <span class="n">json_element</span><span class="p">[</span><span class="s">"type"</span><span class="p">]</span> <span class="o">=</span> <span class="s">"branch"</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">json_element</span><span class="p">[</span><span class="s">"type"</span><span class="p">]</span> <span class="o">=</span> <span class="s">"leaf"</span> + <span class="k">del</span> <span class="n">json_element</span><span class="p">[</span><span class="s">"children"</span><span class="p">]</span> + + <span class="n">output</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">json_element</span><span class="p">)</span> + + <span class="k">return</span> <span class="n">output</span> +</code></pre></div></div> + +<p>Finally, the <code class="highlighter-rouge">dict</code> is written to a file with <code class="highlighter-rouge">json.dump</code></p> + +<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">json</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">mind_map</span><span class="p">,</span> <span class="nb">open</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="nb">file</span> <span class="o">+</span> <span class="s">".json"</span><span class="p">,</span> <span class="s">"w"</span><span class="p">))</span> +</code></pre></div></div> + +<p>The whole script (with comments) can be found on my <a href="https://gist.github.com/Ewpratten/0d8f7c7371380c9ca8adcfc6502ccf84#file-parser-py">GitHub account</a>.</p> + +<h2 id="the-output">The output</h2> +<p>Running the <code class="highlighter-rouge">.mm</code> file from above through the script gives:</p> + +<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="w"> + </span><span class="p">{</span><span class="w"> + </span><span class="s2">"name"</span><span class="p">:</span><span class="s2">"Master Node"</span><span class="p">,</span><span class="w"> + </span><span class="s2">"children"</span><span class="p">:[</span><span class="w"> + </span><span class="p">{</span><span class="w"> + </span><span class="s2">"name"</span><span class="p">:</span><span class="s2">"Child branch"</span><span class="p">,</span><span class="w"> + </span><span class="s2">"children"</span><span class="p">:[</span><span class="w"> + </span><span class="p">{</span><span class="w"> + </span><span class="s2">"name"</span><span class="p">:</span><span class="s2">"Children 1"</span><span class="p">,</span><span class="w"> + </span><span class="s2">"type"</span><span class="p">:</span><span class="s2">"leaf"</span><span class="w"> + </span><span class="p">},</span><span class="w"> + </span><span class="p">{</span><span class="w"> + </span><span class="s2">"name"</span><span class="p">:</span><span class="s2">"Children 2"</span><span class="p">,</span><span class="w"> + </span><span class="s2">"type"</span><span class="p">:</span><span class="s2">"leaf"</span><span class="w"> + </span><span class="p">}</span><span class="w"> + </span><span class="p">],</span><span class="w"> + </span><span class="s2">"type"</span><span class="p">:</span><span class="s2">"branch"</span><span class="w"> + </span><span class="p">}</span><span class="w"> + </span><span class="p">],</span><span class="w"> + </span><span class="s2">"type"</span><span class="p">:</span><span class="s2">"branch"</span><span class="w"> + </span><span class="p">}</span><span class="w"> +</span><span class="p">]</span><span class="w"> +</span></code></pre></div></div> + +<h2 id="the-next-step">The next step</h2> +<p>This script just translates a <code class="highlighter-rouge">.mm</code> file to JSON. Nothing else. Next, I want to convert this to a library, and add a JSON to <code class="highlighter-rouge">.mm</code> function as well. This leads into my ultimate goal for this project.</p> + +<p>I want a script that I can drop in the root of any project to build a <a href="https://gource.io/">Gource</a>-style visualization of the folder structure. This will give me a way to make cool visualizations for lessons on the robotics team.</p>While working on an assignment with Coggle today, I noticed an interesting option in the save menu. Download as .mm file. Having rarely worked with mind maps before, and only doing it online, it never occured to me that someone would have a file format for it. So I took a look.Taking a look back at GMAD2019-07-13T10:43:00-04:002019-07-13T10:43:00-04:00http://0.0.0.0:4000/blog/2019/07/13/Lookback-GMAD<p>One day, back in June of 2018, I was both looking for a new project to work on, and trying to decide which Linux distro to install on one of my computers. From this, a little project was born. <a href="/gmad">Give Me a Distro</a> (or, GMAD, as I like to call it) is a little website that chooses a random distribution of Linux and shows a description of what you are about to get yourself into, and a download link for the latest ISO.</p> <h2 id="backend-tech">Backend tech</h2> <p>This is one of the simplest projects I have ever made. All the backend does is:</p> @@ -481,15 +595,4 @@ __<span class="o">()</span> <span class="o"&g <li>Have mentors do “guest presentations”</li> <li>Dedicate a day to robot driving lessons</li> <li>Use a custom library with wrappers and tools built by me to provide easy interfaces for new programmers</li> -</ul>Over the past two years (2018 / 2019), I have been a member of my school’s FRC team, Raider Robotics. Specifically, a programmer.I made a new song!2019-06-17T06:20:00-04:002019-06-17T06:20:00-04:00http://0.0.0.0:4000/blog/2019/06/17/AMM2M1-release<p>I am currently taking a class in school called <a href="https://www.facebook.com/studio225beal/">Music and computers (AMM2M)</a>, where as part of the class, whe get together into bands, and produce a song. After taking a break from music production for over a year, we have released our song for the class (we do two songs, but the second is not finished yet).</p> - -<h2 id="my-contribution">My contribution</h2> -<p>My main contribution to the project was a mix of live drumming, and most of the song’s MIDI work. The song is far from perfect, but pretty good for the time we had to produce it.</p> - -<h2 id="just-give-me-the-song">Just give me the song!</h2> -<p>Ok. Ok. Here is the song:</p> - -<audio controls=""> -<source src="/assets/audio/SpamPhoneCalls.mp3" type="audio/mpeg" /> -Your browser does not support audio players -</audio>I am currently taking a class in school called Music and computers (AMM2M), where as part of the class, whe get together into bands, and produce a song. After taking a break from music production for over a year, we have released our song for the class (we do two songs, but the second is not finished yet). \ No newline at end of file +</ul>Over the past two years (2018 / 2019), I have been a member of my school’s FRC team, Raider Robotics. Specifically, a programmer. \ No newline at end of file diff --git a/_site/index.html b/_site/index.html index 4278a28..e1f67b5 100644 --- a/_site/index.html +++ b/_site/index.html @@ -127,12 +127,12 @@ diff --git a/assets/images/mindmap-simple.png b/assets/images/mindmap-simple.png new file mode 100644 index 0000000000000000000000000000000000000000..44565fe642709f6a74b71c463138da75bb2334aa GIT binary patch literal 25758 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 u1W?N>*n?SnW