<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Stan Sidel's Blog]]></title><description><![CDATA[Stan Sidel's Blog]]></description><link>https://dev.stan.sidel.family</link><generator>RSS for Node</generator><lastBuildDate>Thu, 14 May 2026 01:26:54 GMT</lastBuildDate><atom:link href="https://dev.stan.sidel.family/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[US Universities with Late Application Deadlines]]></title><description><![CDATA[Based on https://blog.prepscholar.com/colleges-with-late-application-deadlines-complete-list.
Code to fetch information about the universities from the list above:
# %%
#!pip3 install requests
# !pip3 install ipywidgets

import requests
import csv
fr...]]></description><link>https://dev.stan.sidel.family/us-universities-with-late-application-deadlines</link><guid isPermaLink="true">https://dev.stan.sidel.family/us-universities-with-late-application-deadlines</guid><dc:creator><![CDATA[Stan Sidel]]></dc:creator><pubDate>Mon, 19 Feb 2024 18:04:07 GMT</pubDate><content:encoded><![CDATA[<iframe width="100%" height="600" src="//jsfiddle.net/ssidelnikov/w2gdu34p/7/embedded/result/"></iframe>

<p>Based on <a target="_blank" href="https://blog.prepscholar.com/colleges-with-late-application-deadlines-complete-list">https://blog.prepscholar.com/colleges-with-late-application-deadlines-complete-list</a>.</p>
<p>Code to fetch information about the universities from the list above:</p>
<pre><code class="lang-python"><span class="hljs-comment"># %%</span>
<span class="hljs-comment">#!pip3 install requests</span>
<span class="hljs-comment"># !pip3 install ipywidgets</span>

<span class="hljs-keyword">import</span> requests
<span class="hljs-keyword">import</span> csv
<span class="hljs-keyword">from</span> typing <span class="hljs-keyword">import</span> List, Dict, Optional
<span class="hljs-keyword">from</span> ipywidgets <span class="hljs-keyword">import</span> IntProgress
<span class="hljs-keyword">from</span> IPython.display <span class="hljs-keyword">import</span> display

<span class="hljs-comment"># %%</span>
MAPS_API_KEY = <span class="hljs-string">"&lt;YOUR_KEY&gt;"</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">fetch_uni_info</span>(<span class="hljs-params">name: str</span>) -&gt; Optional[Dict[str, str]]:</span>
    base_url_place = <span class="hljs-string">'https://maps.googleapis.com/maps/api/place/findplacefromtext/json'</span>
    params_place = {
        <span class="hljs-string">'input'</span>: name,
        <span class="hljs-string">'inputtype'</span>: <span class="hljs-string">'textquery'</span>,
        <span class="hljs-string">'fields'</span>: <span class="hljs-string">'name,place_id'</span>,
        <span class="hljs-string">'types'</span>: <span class="hljs-string">'(universities)'</span>,
        <span class="hljs-comment"># 'region': 'us',</span>
        <span class="hljs-comment"># 'circle': '50000@41.071533,-97.785450',</span>
        <span class="hljs-string">'key'</span>: MAPS_API_KEY,
    }

    response_place = requests.get(base_url_place, params=params_place)
    <span class="hljs-keyword">if</span> response_place.status_code != <span class="hljs-number">200</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">None</span>

    data_place = response_place.json()

    <span class="hljs-keyword">if</span> len(data_place[<span class="hljs-string">"candidates"</span>]) &lt; <span class="hljs-number">1</span>:
       <span class="hljs-keyword">return</span> <span class="hljs-literal">None</span>

    place_id = data_place[<span class="hljs-string">"candidates"</span>][<span class="hljs-number">0</span>][<span class="hljs-string">"place_id"</span>]

    base_url_info = <span class="hljs-string">'https://maps.googleapis.com/maps/api/place/details/json'</span>
    params_info = {
        <span class="hljs-string">'place_id'</span>: place_id,
        <span class="hljs-string">'fields'</span>: <span class="hljs-string">'name,address_components,adr_address,formatted_address,website,geometry/location'</span>,
        <span class="hljs-string">'key'</span>: MAPS_API_KEY
    }

    response_info = requests.get(base_url_info, params=params_info)
    <span class="hljs-keyword">if</span> response_info.status_code != <span class="hljs-number">200</span>:
       <span class="hljs-keyword">return</span> <span class="hljs-literal">None</span>

    data_info = response_info.json()[<span class="hljs-string">'result'</span>]

    components = data_info[<span class="hljs-string">"address_components"</span>]
    <span class="hljs-comment"># print(components)</span>
    city = next((e[<span class="hljs-string">"short_name"</span>] <span class="hljs-keyword">for</span> e <span class="hljs-keyword">in</span> components <span class="hljs-keyword">if</span> <span class="hljs-string">"locality"</span> <span class="hljs-keyword">in</span> e[<span class="hljs-string">"types"</span>] <span class="hljs-keyword">or</span> <span class="hljs-string">"postal_town"</span> <span class="hljs-keyword">in</span> e[<span class="hljs-string">"types"</span>]), <span class="hljs-literal">None</span>)
    state = next(e[<span class="hljs-string">"short_name"</span>] <span class="hljs-keyword">for</span> e <span class="hljs-keyword">in</span> components <span class="hljs-keyword">if</span> <span class="hljs-string">"administrative_area_level_1"</span> <span class="hljs-keyword">in</span> e[<span class="hljs-string">"types"</span>])
    country = next(e[<span class="hljs-string">"short_name"</span>] <span class="hljs-keyword">for</span> e <span class="hljs-keyword">in</span> components <span class="hljs-keyword">if</span> <span class="hljs-string">"country"</span> <span class="hljs-keyword">in</span> e[<span class="hljs-string">"types"</span>])

    lat = data_info[<span class="hljs-string">"geometry"</span>][<span class="hljs-string">"location"</span>][<span class="hljs-string">"lat"</span>]
    lon = data_info[<span class="hljs-string">"geometry"</span>][<span class="hljs-string">"location"</span>][<span class="hljs-string">"lng"</span>]

    <span class="hljs-keyword">return</span> {
        <span class="hljs-string">"website"</span>: data_info[<span class="hljs-string">"website"</span>] <span class="hljs-keyword">if</span> <span class="hljs-string">"website"</span> <span class="hljs-keyword">in</span> data_info <span class="hljs-keyword">else</span> <span class="hljs-literal">None</span>,
        <span class="hljs-string">"city"</span>: city,
        <span class="hljs-string">"state"</span>: state,
        <span class="hljs-string">"country"</span>: country,
        <span class="hljs-string">"formatted_address"</span>: data_info[<span class="hljs-string">"formatted_address"</span>],
        <span class="hljs-string">"lat"</span>: lat,
        <span class="hljs-string">"lon"</span>: lon
    }

fetch_uni_info(<span class="hljs-string">"Yonsei University"</span>)

<span class="hljs-comment"># %%</span>
unis = []

<span class="hljs-keyword">with</span> open(<span class="hljs-string">'input.csv'</span>) <span class="hljs-keyword">as</span> csv_file:
    csv_reader = csv.reader(csv_file, delimiter=<span class="hljs-string">','</span>)
    is_header = <span class="hljs-literal">True</span>
    <span class="hljs-keyword">for</span> row <span class="hljs-keyword">in</span> csv_reader:
        <span class="hljs-keyword">if</span> is_header:
            is_header = <span class="hljs-literal">False</span>
            <span class="hljs-keyword">continue</span>
        unis.append({<span class="hljs-string">"name"</span>: row[<span class="hljs-number">0</span>], <span class="hljs-string">"deadline"</span>: row[<span class="hljs-number">1</span>]})

unis


<span class="hljs-comment"># %%</span>
uni_infos = {}

<span class="hljs-comment"># %%</span>
f = IntProgress(min=<span class="hljs-number">0</span>, max=len(unis))
display(f)

<span class="hljs-keyword">for</span> uni <span class="hljs-keyword">in</span> unis:
    f.value += <span class="hljs-number">1</span>
    uni_name = uni[<span class="hljs-string">"name"</span>]
    <span class="hljs-keyword">if</span> uni_name <span class="hljs-keyword">in</span> uni_infos:
        <span class="hljs-keyword">continue</span>
    print(<span class="hljs-string">"Fetching info for "</span> + uni_name)
    uni_info = fetch_uni_info(uni_name)
    <span class="hljs-keyword">if</span> uni_info:
        uni_infos[uni_name] = uni_info

<span class="hljs-comment"># %%</span>
print(<span class="hljs-string">"Len:"</span>, len(uni_infos.keys()))
list(uni_infos.keys())

<span class="hljs-comment"># %%</span>
header = [<span class="hljs-string">"University"</span>, <span class="hljs-string">"Application Deadline"</span>, <span class="hljs-string">"Website"</span>, <span class="hljs-string">"City"</span>, <span class="hljs-string">"State"</span>, <span class="hljs-string">"Country"</span>, <span class="hljs-string">"Full Address"</span>, <span class="hljs-string">"Latitude"</span>, <span class="hljs-string">"Longitude"</span>]

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">build_row</span>(<span class="hljs-params">uni_input: Dict[str, str]</span>) -&gt; List[str]:</span>
    name = uni_input[<span class="hljs-string">"name"</span>]
    deadline = uni_input[<span class="hljs-string">"deadline"</span>]
    website, city, state, country, formatted_address, lat, lon = <span class="hljs-literal">None</span>, <span class="hljs-literal">None</span>, <span class="hljs-literal">None</span>, <span class="hljs-literal">None</span>, <span class="hljs-literal">None</span>, <span class="hljs-literal">None</span>, <span class="hljs-literal">None</span>
    <span class="hljs-keyword">if</span> name <span class="hljs-keyword">in</span> uni_infos:
        info = uni_infos[name]
        website = info[<span class="hljs-string">"website"</span>]
        city = info[<span class="hljs-string">"city"</span>]
        state = info[<span class="hljs-string">"state"</span>]
        country = info[<span class="hljs-string">"country"</span>]
        formatted_address = info[<span class="hljs-string">"formatted_address"</span>]
        lat = info[<span class="hljs-string">"lat"</span>]
        lon = info[<span class="hljs-string">"lon"</span>]

    <span class="hljs-keyword">return</span> [name, deadline, website, city, state, country, formatted_address, lat, lon]

build_row(unis[<span class="hljs-number">0</span>])

<span class="hljs-comment"># %%</span>

<span class="hljs-keyword">with</span> open(<span class="hljs-string">'unis_with_late_deadlines.csv'</span>, <span class="hljs-string">'w'</span>, encoding=<span class="hljs-string">'UTF-8'</span>) <span class="hljs-keyword">as</span> f:
    writer = csv.writer(f)

    writer.writerow(header)

    writer.writerows(map(<span class="hljs-keyword">lambda</span> uni: build_row(uni), unis))

<span class="hljs-comment"># %%</span>
<span class="hljs-comment"># Produce JS code for adding markers to the map. See https://developers.google.com/maps/documentation/javascript/markers#accessible</span>

print(<span class="hljs-string">"const unis: [google.maps.LatLngLiteral, string][] = ["</span>)

<span class="hljs-keyword">for</span> uni <span class="hljs-keyword">in</span> unis:
    name = uni[<span class="hljs-string">"name"</span>]
    deadline = uni[<span class="hljs-string">"deadline"</span>]
    <span class="hljs-keyword">if</span> name <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> uni_infos:
        <span class="hljs-keyword">continue</span>
    info = uni_infos[name]
    full_name = name + <span class="hljs-string">" ("</span> + deadline + <span class="hljs-string">")"</span>
    print(<span class="hljs-string">"    [{ lat: "</span> + str(info[<span class="hljs-string">"lat"</span>]) + <span class="hljs-string">", lng: "</span> + str(info[<span class="hljs-string">"lon"</span>]) + <span class="hljs-string">" }, \""</span> + full_name + <span class="hljs-string">"\", \""</span> + deadline + <span class="hljs-string">"\"],"</span>)

print(<span class="hljs-string">"]"</span>)
</code></pre>
]]></content:encoded></item><item><title><![CDATA[SwiftUI View Preview Selecting Issue]]></title><description><![CDATA[If you have ever tried to select an element in the preview (Canvas) of your SwiftUI view, you may have noticed that sometimes it doesn't get selected. Instead, the whole simulator window gets selected, and the Attributes Inspector reads “Multiple Sel...]]></description><link>https://dev.stan.sidel.family/swiftui-view-preview-selecting-issue</link><guid isPermaLink="true">https://dev.stan.sidel.family/swiftui-view-preview-selecting-issue</guid><category><![CDATA[SwiftUI]]></category><category><![CDATA[Xcode]]></category><dc:creator><![CDATA[Stan Sidel]]></dc:creator><pubDate>Sat, 20 May 2023 14:59:16 GMT</pubDate><content:encoded><![CDATA[<p>If you have ever tried to select an element in the preview (Canvas) of your SwiftUI view, you may have noticed that sometimes it doesn't get selected. Instead, the whole simulator window gets selected, and the Attributes Inspector reads “Multiple Selection”. This can be a frustrating issue when you are trying to debug or modify your code.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1684594132371/88d7c6a1-3d8c-465e-a84f-69dd1ead525a.png" alt="A preview of a SwiftUI view when the user tried to select the internal Text view but it didn’t work" class="image--center mx-auto" /></p>
<p>A preview of a SwiftUI view when the user tried to select the internal Text view but it didn’t work</p>
<h1 id="heading-reason-one">Reason One</h1>
<p>In some cases, the culprit may be creating a new return variable in the reduce (map?) closure. For example, the following code would cause the issue:</p>
<pre><code class="lang-swift">emotions.<span class="hljs-built_in">reduce</span>(<span class="hljs-type">Text</span>(<span class="hljs-string">""</span>)) { result, emotion <span class="hljs-keyword">in</span>
    <span class="hljs-keyword">var</span> result = result
    <span class="hljs-keyword">if</span> emotion != emotions.first {
        result = result + <span class="hljs-type">Text</span>(<span class="hljs-string">", "</span>)
    }
    <span class="hljs-keyword">return</span> result + <span class="hljs-type">Text</span>(emotion)
}
</code></pre>
<p>To avoid this issue, we can modify the code to return just a modification of the initial result, without creating a new variable. The code for our sample case that doesn’t break the preview may look like this:</p>
<pre><code class="lang-swift">emotions.<span class="hljs-built_in">reduce</span>(<span class="hljs-type">Text</span>(<span class="hljs-string">""</span>)) { result, emotion <span class="hljs-keyword">in</span>
    result
    + <span class="hljs-type">Text</span>(emotion == emotions.first ? <span class="hljs-string">""</span> : <span class="hljs-string">", "</span>)
    + <span class="hljs-type">Text</span>(emotion)
}
</code></pre>
<p>Another workaround is to move the code as-is into a separate function:</p>
<pre><code class="lang-swift"><span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">TestView</span>: <span class="hljs-title">View</span> </span>{
    <span class="hljs-keyword">let</span> emotions: [<span class="hljs-type">String</span>]

    <span class="hljs-keyword">var</span> body: some <span class="hljs-type">View</span> {
        emotions.<span class="hljs-built_in">reduce</span>(<span class="hljs-type">Text</span>(<span class="hljs-string">""</span>)) { result, emotion <span class="hljs-keyword">in</span>
            <span class="hljs-keyword">self</span>.buildText(result: result, emotion: emotion, isFirst: emotion == emotions.first)
        }
    }

    <span class="hljs-keyword">private</span> <span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">buildText</span><span class="hljs-params">(result: Text, emotion: String, isFirst: Bool)</span></span> -&gt; <span class="hljs-type">Text</span> {
        <span class="hljs-keyword">var</span> result = result
        <span class="hljs-keyword">if</span> !isFirst {
            result = result + <span class="hljs-type">Text</span>(<span class="hljs-string">", "</span>)
        }
        <span class="hljs-keyword">return</span> result + <span class="hljs-type">Text</span>(emotion)
    }
}
</code></pre>
<p>The full code of the troubling case:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">import</span> SwiftUI

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">TestView</span>: <span class="hljs-title">View</span> </span>{
    <span class="hljs-keyword">let</span> emotions: [<span class="hljs-type">String</span>]

    <span class="hljs-keyword">var</span> body: some <span class="hljs-type">View</span> {
        emotions.<span class="hljs-built_in">reduce</span>(<span class="hljs-type">Text</span>(<span class="hljs-string">""</span>)) { result, emotion <span class="hljs-keyword">in</span>
            <span class="hljs-keyword">var</span> result = result
            <span class="hljs-keyword">if</span> emotion != emotions.first {
                result = result + <span class="hljs-type">Text</span>(<span class="hljs-string">", "</span>)
            }
            <span class="hljs-keyword">return</span> result + <span class="hljs-type">Text</span>(emotion)
        }
    }
}

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">TestView_Previews</span>: <span class="hljs-title">PreviewProvider</span> </span>{
    <span class="hljs-keyword">static</span> <span class="hljs-keyword">var</span> previews: some <span class="hljs-type">View</span> {
        <span class="hljs-type">TestView</span>(emotions: [<span class="hljs-string">"antsy"</span>, <span class="hljs-string">"anxious"</span>])
    }
}
</code></pre>
<details><summary>Why so complex reduce with Texts?</summary><div data-type="detailsContent">This code reduces <code>Text</code>s, not <code>String</code>s, to get advantage of the <code>LocalizedStringKey</code> type. All of the strings that goes to its constructor are automatically exported with the Product → Export Localizations menu. When dealing with the <code>LocalizedString</code> API, we need to manually add these string to the localization files. In the real-world code the emotion is not a string but rather an enum that returns a <code>LocalizedStringKey</code> in the <code>localized</code> computed property. We pass this <code>localized</code> property to the <code>Text</code> constructor so that it generates the correct localized string.</div></details>

<h1 id="heading-reason-two">Reason Two</h1>
<p>Another reason why this issue may occur is when using a <code>NavigationView</code> in the view. You can select the navigation view, but not any subview. To solve this, you can move all the subviews of the navigation view into a separate view.</p>
<p>For example, the following code would cause the issue:</p>
<pre><code class="lang-swift"><span class="hljs-keyword">import</span> SwiftUI

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">TestView</span>: <span class="hljs-title">View</span> </span>{
    <span class="hljs-keyword">var</span> body: some <span class="hljs-type">View</span> {
        <span class="hljs-type">NavigationView</span> {
            <span class="hljs-type">VStack</span> {
                <span class="hljs-type">Text</span>(<span class="hljs-string">"One"</span>)
                <span class="hljs-type">Text</span>(<span class="hljs-string">"Two"</span>)
                <span class="hljs-type">Text</span>(<span class="hljs-string">"Three"</span>)
            }
        }
    }
}

<span class="hljs-class"><span class="hljs-keyword">struct</span> <span class="hljs-title">TestView_Previews</span>: <span class="hljs-title">PreviewProvider</span> </span>{
    <span class="hljs-keyword">static</span> <span class="hljs-keyword">var</span> previews: some <span class="hljs-type">View</span> {
        <span class="hljs-type">TestView</span>()
    }
}
</code></pre>
<p>The only way to solve this issue so far is to move all the subviews of the navigation view into a separate view.</p>
]]></content:encoded></item></channel></rss>