Hi Arben, I have another question about Manipulate and it ties in with my questions from 3 days ago about 'Stepping back' to previous settings in Manipulate. One has to be quite careful not to create a loop in a Manipulate construct.
E,g. a= a+2 gives already a loop. If done like aNew = a+ 2, then it's ok.
More 'funny things' might happen in a more complex Manipulate construction. My question is :
How is the order of the calculations in a Manipulate? Does it go from top to bottom, like line for line (and left to right)? Always?
What if I change a parameter (slider) whose appearance is only after 20 lines of code? Is still all the code run from the top, or does the re-calculation start where the changed value first appears (e.g. line 20)? How can I step through the code and watch the changing variables, like in 'Step-Debug'?
Thanks a lot, Bert
|
|
Hi Arben, I would really appreciate if you could shed some light on these questions of mine. I hope you find the time for it :-) I read through both "Dynamic & Manipulate Notes" and the "Advanced Dynamic & Manipulate Notes".
I could not find anything about the order of execution of the lines of code or step Debug in a Manipulate construct. Thanks a lot,
Beat
|
|
Hey Bert! I didn't know the answer to this one off the top of my head. After some investigation, I have to say "it's complicated." From the Advanced Dynamic Functionality Tutorial:
Dynamic expressions can be nested, and the system takes great care to update them only when necessary. Particularly when the contents of a Dynamic contain further interactive elements, it is important to keep track of what will stay static and what will update, when a given variable is changed.
It seems as if for any given dynamic expression, there's a step which involves "tracking down" what pieces of the expression can/will change when certain dynamic variables are updated, and it's those pieces which end up being reevaluated.
|
|
Thanks Arben, for your help and work. It certainly is quite complicated and I started wondering after I found that the code inside Manipulate is not necessarily executed from top to bottom. It is getting even more complicated if there are Dynamic functions explicit withing the Manipulate. Maybe I can come up with some Flags that get set when some line of code is re-executed. I'll have to try. I will read through the Advanced manipulate and Dynamic paper again :-) Best, Bert
|
|
Part of the issue here—and I think why you probably didn't think that the quoted section was useful when you first read it—is that Manipulate is making its own DynamicModule under the hood. This means that even if you're not typing Dynamic[x] , the fact that you have (say) {x,1,10} as the second argument to Manipulate means that the constructed DynamicModule does have Dynamic[x] in there—which is why the quoted section is actually relevant, even if you aren't personally typing Dynamic[x] .
|
|
Very good point, Arben :-)
|
|
I am having email problems. How do I join the class without today's link? Sorry about this!
|
|
@Paul Tikotin, we'll send your join link to your email, or you can contact us at wolfram-u@wolfram.com to provide a different address, if you're having trouble with gmail. You can also go to the webinar page to register and receive a join link using a different email address. Email communication of some sort will be needed.
|
|
I think I have just sorted the problem,...Thank you!
|
|
How about a separate Wolfram Community discussion to speculate/brainstorm about L2 cert projects? Anyone can create a new discussion, but it might be good to have the "seal of approval" if @Arben Kalziqi or @Jamie Peterson were to create it. :) I am looking at a Wolfram Examples project showing muscle co-activation of hand flexors/extensors, arm flexors/extensors, and arm pronators/supinators. The beautiful Anatomy package has the ability to do color illustrations; I can graphically show the muscles involved in particular co-activations. Apparently, the Anatomy package also has identifiers for the antagonist pairs; I need to investigate that. Apologies if those words make no sense; it's better in pictures.
|
|
While I (hopefully clearly) do enjoy answering everybody's questions here, for something as involved as the Level 2 projects I'm afraid it's not really feasible from a time/involvement perspective. Like Jamie said, please do take advantage of office hours, and we may well offer more things like this in the future. (Actually, typing that reminds me that we have something in the cards for like, an "interesting example + office hour Fridays" series... we'll see if that comes to fruition!)
|
|
While I (hopefully clearly) do enjoy answering everybody's questions
here, for something as involved as the Level 2 projects I'm afraid
it's not really feasible from a time/involvement perspective.
Whoa! While I can't speak for @Kari Grafton, my intent was never to turn this proposed discussion group into a place for Wolfram staffers to guide us through any steps of the L2 project process. My intention was to have an informal conversation between participants in the process. In what I'm visualizing, it's probably the case that WR staff participation in the discussion would be counterproductive. As proposed, the L2 cert process is a solitary interaction between a developer and Wolfram Research. The process is isolated; there's no sense of community in that process. A successful course (like this one) nurtures a sense of community in the participants; that's what I was looking for in a L2 Wolfram Community discussion. Maybe the discussion group is about encouraging participants to create a project worthy of putting in one of the designated repositories. That project may or may not be sufficient for a L2 certification; that's not really important. I think this is very different from what Arben and Jamie were hearing when they reacted to this discussion. What is clear: I need to choose words carefully for the first message of the discussion group. Let people know this has nothing to do with anything official that WR is doing. Let them know it's about community. The discussion is more like Stephen Covey's idea in The 8th Habit: Find Your Voice, and Inspire Others to Find Theirs
|
|
In that case, I support y'all wholeheartedly (imagine I could use emojis here and added a :sweat_smile: at the end there, okay).
|
|
My best suggestion is to use today's Study Group survey to request your registration at the March 1 instructor office hours, which will also be available as part of the upcoming Programming Proficiency course sequence. Register for the course sequence here.
|
|
Great, thank you! I did request registration for the office hours. And I agree that a L2 discussion board geared towards the participants is a great idea.
|
|
Hi Jamie, Cassidy, Abrita, Arben! Thank you for all your hard work that goes into making these study groups enjoyable. [big smiley] I enjoyed the fill-in-the-blank format of the Level 1 quiz. Keep that coming. The Level 2 Certificate is on my agenda (the Nutrition Report looks interesting) as are almost every new webinar and WSG. Artisinal Calculus, why, yes, I think I will! I'm sleeping in today but I will see y'all soon. Stay safe. Stay healthy.
Lori
|
|
Same! I can't get enough of these webinars and try to do every one that looks like it's even remotely related to something I might use. Or just looks particularly interesting.
|
|
Hi Kari! Nice to meet you! Absolutely. My goal is to learn at least one new piece of creative programming each time, be reminded of a command I may have forgotten, etc. I am seldom disappointed :D Do you collect session notebooks, too? They're like conference handouts. There are always "goodies" inside.
|
|
Thanks Lori! We always enjoy having you with us. Hopefully you enjoy the review recording and notebook if you'd like to peruse them after sleeping in!
|
|
Aww, that's a very nice thing to say. Thank you, Arben!!! Will do! Have a fun weekend :D
|
|
I am trying to rid my code of Do loops as suggested in the training, but I am having some difficulty in getting the simple example in my notebook to work. It is not clear to me how to get the names to cycle through the example.
I have several sources of data each with a key value that I am trying to combine into one variable.
This is how I am doing it now. I believe if I could figure out how to do the simple example in my attached notebook, I could make the below work.
Do[bE1defgrad[[i]] =
Map[Append[#, Select[sEDNH, MemberQ[#, bE1[[i]]] &][[1]][[3]]] &,
Map[Append[#,
Select[pressure, MemberQ[#, bE1[[i]]] &][[1]][[2]]] &,
Select[defGrad, MemberQ[#, bE1[[i]]] &]]];,
{i, 1, bE1len}]
|
|
Hi Philip, The code you posted is incomplete, there are several symbols that are not defined sEDNH , pressure , defGrad , .... I also don't understand what you are trying to accomplish with combined . It just adds an additional level of nesting to dgrad because names includes all of the elements in dgrad
dgrad == First /@ combined
(* True *)
If you just want to pick out the matches to names here is a functional way to do it. There is no need to initialize combined
combined = Select[dgrad, MemberQ[names, First@#] &]
|
|
Hey Philip—agree with Rohit here; I'm not sure what you're trying to do exactly. If you could upload a version of the notebook where you've defined everything that you're using and where you've explained what each "step" is supposed to do (like by saying "i have [input], and it does [xyz], resulting in [output]"), I'm sure I'd be able to help.
|
|
Thanks for the feedback. I am reading several files into my notebook and I ended up simplifying it too much without providing the needed context. Hopefully the attached notebook rectifies this.
I basically have three lists that contain data keyed to a list of names. I wish to combine all of the data into one list, but only for the items in the list names. My background is Fortran, so I instantly think of loops, however the Wolfram language intrigues me and I really want to use it effectively.
Phil
|
|
Hi Philip, I have modified your notebook and added a solution to the end. Light green cells are ones I added.
Attachments:
|
|
Rohit,
Thanks for the solution. It looks much better that the Do loop and gives me new avenues to explore.
Phil
|
|
package question All examples of creating a package (after foo::usage=...;bar::usage=...., etc) use
Begin["`Private`"]
and then function bodies follow. Does the word "Private" have some particular significance. What would be the problem with using some other word like
Begin["`NotPrivateAtAll`"]
How is this designation actually used?
|
|
Does the word "Private" have some particular significance. What would
be the problem with using some other word like [...]
"Private" has no significance. If you go to the Wolfram Language Documentation for Begin, you'll see the examples there use "MyContext`". "Private" is not a keyword in the WL, but [IMHO] the fact that it is a keyword in many programming languages means it should probably be avoided in examples in Wolfram courses. OTOH, "MyContext" is definitely un-keywordy. It's really helpful to use the Wolfram Language Documentation as the first place to go with questions like this. I don't think that Arben has emphasized the wonderful Wolfram documentation in this course. Docs are available on the web; they are also typically installed in a Mathematica install and can be accessed through a Mathematica window. Carpe documenta!
|
|
If there are bugs/shortcomings in the documentation, you can file a support ticket with Wolfram. As far as Private not being a keyword, I just looked up that word in the documentation. Simple. "Private" the String is used as an option in some functions, but that doesn't leak out and affect other things. If a word isn't mentioned in the doc entry for some function, it shouldn't have any magic way to affect that function. The other thing I noticed with your questions: if you're curious what happens when you do X, just try it. If the kernel behaves in some inexplicable way, that's the point in time to investigate further. I imagine Stephen Wolfram sitting (or standing) in his office in MA; I bet it's in his muscle memory just to try something about before looking it up in the docs or (gasp!) asking another staffer for clarification.
|
|
Is there any difference between
Proficiency in Wolfram Language Level 1 Certification
and
Proficiency in Mathematica Level 1 Certification ?
It seems that the requirements and the process are the same.
|
|
Good question! While there is significant overlap between the Wolfram Language and Mathematica Level 1 certifications, we are making changes to focus the Wolfram Language certification on programming, and the Mathematica certification on using the product for technical computation. The Level 1 pages and the exam questions will be reflecting these latest changes in upcoming days and weeks.
|
|
Hi there! I have a question about adding a new variable (Key-> Value) to a list of associations. For instance I recreate the following data
{V1, V2} = {RandomVariate[NormalDistribution[15, 4], 50],
RandomVariate[NormalDistribution[20, 7], 50]}; (*Create two random variables*)
data = AssociationThread[{"Diameter", "Height"} -> #] & /@ Thread[{V1, V2}];
(*Arrange a list of association*)
Suppose I want to add a new variable, for instance, the logarithm of Diameter variable, however, the only way I succed was using a implicit loop using the table function:
V3 = Log[data[[All, "Diameter"]]];
Table[Append[data[[i, All]], "LogDiameter" -> V3[[i]]], {i, 1,
Length[V3]}];
I would like to ask if I could add a variable to the association list avoiding the Table function? Thanks in advance!
|
|
Hi Andres, Here is one way to do it
augmentedData = <|#, "LogDiameter" -> Log[#Diameter]|> & /@ data
Dataset@augmentedData
This relies on the implicit addition of key/value pairs to an Association when wrapped in Association . E.g.
assoc = <|"a" -> 1, "b" -> 2|>
<|assoc, "c" -> 3|>
(* <|"a" -> 1, "b" -> 2, "c" -> 3|> *)
|
|
Hi Andres—here are a few implementations that should get your thoughts moving, If you have access to V1 and V2 directly, you can do:
new = AssociationThread[{"Diameter", "Height", "LogDiameter"} -> #] & /@
Transpose[{V1, V2, V3}];
If you only have direct access to data, you could do this (honestly, I'd do something like this anyway):
new = <|"Diameter" -> #Diameter, "Height" -> #Height,
"LogDiameter" -> Log@#Diameter|> & /@ data;
The fastest and shortest way has got to be something like:
new = Append[#, "LogDiameter" -> Log@#Diameter] & /@ data;
|
|
I just wanted everyone to know that the notebooks for the book "Query" are available at: Query notebooks. I have found them to be a helpful companion to our class.
|
|
When I click on the Grading Rubric link on this page I get
HTTP Error Code 403 Sorry, you do not have permission to access this
item.
|
|
Hi Rohit, this should be fixed now—works for me, as well. You may need to clear cookies/cache to get it to work, though, as a version with the wrong permissions may be cached on your end.
|
|
How to create the association command, "<|", vertical bar?
|
|
It will depend on your keyboard layout, but a QWERTY layout should have the | accessible by pressing shift and . The < is just a less-than sign, so that's <|association here|>.
|
|
Arben The backslash needs to be escaped in the reply window. Shift \ Shift + \
|
|
oh god, it escapes even when there's nothing in front of it? blegh, thanks Rohit! Taiboo: indeed, you want shift + backslash—shift + \
|
|
Hello Arben: You are an excellent instructor and learning a lot. When I open your filled-out notebook file, the file shows up as the notebook, with nice colors. But when I open the file class file, it looks different. Why is that and how to get into a nice notebook format for your class notes?
|
|
Hey Taiboo—we have two versions of our notebooks, generally speaking. One is the instructor version, which I use when teaching live and which we use for making edits. Then, there's a more monochrome "handout" version which has some formatting changed for consistency's sake and to work nicely on the cloud.
|
|
Arben - Two questions:
1. On the Quiz, is there a way to find out which problem(s) we got wrong?
2. My "Day01-ListsAndAssociations-Filled.nb" is filled with NULLs. Is there a way to resolve this?
Thanks in advance,
|
|
- I don't think so, but if you have a question about a particular question you can ask me. (I also think that if you email us, we can manually pull your answers and which were correct.)
- No
Null s for me. You might get them if you don't Enable Dynamics when prompted.
|
|
The quizzes used to indicate which ones were incorrect, but within the last year that was changed. I found the old method of indicating which answers were correct educational and the new method not so much. Thanks, Mitch Sandlin
|
|
I have some questions about the Manipulate construction:
I have a manipulate with let's say 4 adjustable parameters.
How can I make a button (Previous) to go to the previous values, without getting into an endless loop, which can easily happen in a Manipulate, as if one parameter is changed, everything is recalculated. I tried several ways, like putting the values in a nested list, but somehow there is always something that is not working.
Ideally, I want to be able to step back several steps and also forward again (up to the last values I had). I hope my explanation is clear enough :-)
How can I keep the last used values for the 4 parameters when I run the manipulate again?
I believe that in a DynamicModule construction, that goes by itself.
How can I easily save the values of the 4 params as a named Preset? Eg.: Preset1.
I know that I can do 'Paste snapshot, which gives me all of the original code with the values of the moment, along with the result. This takes a lot of Notebook space, especially when the Manipulate code is substantial.
I only want the values of the parameters, so I can load them back in later.
|
|
Great questions, B—any question I can't immediately answer must be pretty great ;). Let's see...
I think I see what you mean, but some clarification wouldn't hurt. Could you provide a working example of a Manipulate and the behavior you'd like for it to exhibit? The thing about Manipulate is that—unless you specify otherwise via TrackedSymbols , Refresh , and similar—it will simply check for any symbol updates and it will re-compute the result. There's no way that's clear to me to get around this; the thing you're manipulating could depend arbitrarily on these inputs and other things, so it sort of needs to be that way. That said, sometimes you have a Manipulate where there's a "constant" piece which is expensive to compute, and the "dynamic" piece lives on top of it and is generally faster to compute. I don't think that that's what you're talking about, but if so, you can use With and Show to great effect for responsiveness—see attached.
I have a kludgy solution for this and your third question. There's nothing stopping you from defining symbols within a Manipulate , so inside your manipulate you could say something like f[bValue=b,...] and then bValue would be Set to whatever the last value you used on your slider (or other interface element). You can use this as the starting point for the parameter too, so you'd simultaneously save all of your symbols and also be able to keep them as the starting point. Here's an example to get you going:
kValue = 1;
Manipulate[
Plot[Sin[(kValue = k) x], {x, 0, 2 \[Pi]}], {{k, kValue}, .5, 3}]
Dynamic@kValue
|
|
Somehow my post got posted under another name, so here I go again ; Thanks Arben for your answers and for the truly excellent teaching you do. You bring something extra to the table, sometimes very subtle. Your teachings are top on all levels :-) For the moment I reply to your answer to my questions 2+3. I had also come up with creating secondary variables for the adjustable parameters in the Manipulate and assign the these params to the secondary variables. This way They are remembered outside the Manipulate loop. Also handy for debugging. Building on your example, I came up with the following, which keeps the last used value when I run Manipulate again. (see code at end). I can also make presets this way and via a Button load them back into Manipulate. I had hoped that there might be an easier way (a Wolfram function) that would do the job, as sometimes I have quite a lot of adjustable parameters in my Manipulates. But it is doable this way. I'll post a Nb about my first question later.
Manipulate[ kValue = k; Plot[Sin[k x], {x, 0, 2 [Pi]}], {{k, kValue}, .5, 3, Appearance -> "Labeled"}]
|
|
Hi Arben,
I've come up with an example Nb.
It covers some of the 'Previous' and 'Next' possibilities, but not yet all.
And it keeps the values last used. Run the first cell before running the Manipulate, in order to provide initial values for the parameters inside Manipulate. What it does is :
1. It keeps it's last values when running the Manipulate again, except for the Random pointsXY, which are newly generated each time the Manipulate is run.
- It steps back and forward (Button 'Previous' and 'Next'). This only works so far for the position of the lines (pointXY).
Click 'Initialize X' and /or 'Initialize Y' buttons a couple of times and you can step back and forward.
I limited the stepping back and forward , so no errors can occur (like asking for the a step before the first or beyond the last step).
Now I will try to be able to step back also for the other parameters, but something does not pan out yet.
Attachments:
|
|
TOPICS It would be great if the following topics are covered, OR if there are other courses which cover them (I appreciate that some of these were touched on a bit): custom packages , non-trivial function bodies, ordinary looping (includingPython-type looping), IDEs which work well, custom types (as in OO programming), name spaces, enums. At least indicate what Wolfram language calls these structures, and where they are. For example, list indexing was covered to excess, but there was only just brief touches of defining complicated functions. Custom packages are crucial for organizing any but the simplest programs, and ditto for IDEs. Sometimes speed is not important but flexibility in looping might be needed. Etc. Thank you
|
|
Thanks for the suggestions, Steven—we'll cover some of this in the coming days, and the full course offers a bit more insight than the slightly condensed study group. Once the full course is out later this month, please feel free to attend and tell us directly what you thought, if you'd like!
|
|
Not in the file provided.
|
|
Hi Taiboo, the amoeba folder where all of the materials live should have a data folder now which has all of the data used for today's presentation—as well as tomorrow's.
|
|
The 2D slider
Manipulate[coordinate, {{coordinate, {0, 0}, "Coordinate"}, {-1, -1}, {1, 1}}] (* 2D slider *)
How would I do a 3D sider?
Manipulate[coordinate, {{coordinate, {0, 0,0}, "Coordinate"}, {-1, -1,-1}, {1, 1,1}}] (* 3D slider *)
does not work
|
|
Doug, it would be great to have a 3D Slider.
Unfortunately that is not possible on a 2D screen. How would you want to adjust the 3rd (z) axis on a 2D surface?
I have been thinking more than 15 years about this and only have come up with complicated solutions, which are not truly 3D.
|
|
We Create 3D graphics on a 2D surface so we should be able to create a 3D slider . I have noticed recently how graphics programs use a 3 button mouse to allow 3D movement in a 3D graphic , Is this not a possibility
|
|
We create 3D images on a 2D surface by means of perspective.
To actually control 3 independent axes, you'll need 3 independent 'movements'.
Of course, with extra buttons or scroll-wheels, you can add 3 third dimension, but never with a onscreen 3D slider. What you could do, is assign the z direction to e.g. the y direction when ta button is pressed.
But again, this would not be a real 3D slider, more of a work around.
|
|
Doug, it would be great to have a 3D Slider. Unfortunately that is not
possible on a 2D screen. How would you want to adjust the 3rd (z) axis
on a 2D surface? I have been thinking more than 15 years about this
and only have come up with complicated solutions, which are not truly
3D.
If definitely possible on a 3D surface -- like what the Apple Vision Pro headset provides. That's why Apple is making such a big noise WRT the concept of "spatial computing". Check out the guided tour video published by Apple to get a taste of this. I suspect the hands-on demo -- now available at Apple stores -- would give a much better idea what this is all about. I fondly hope the Wolfram Research brain trust is checking out this tech and prototyping how they can use this tech for brilliant Spatial Computing visualizations. On the 3D front, there is the work by Joan Horvath and Rich Cameron who have 3D printed objects designed to teach mathematical concepts: Make: Calculus, Make: Geometry, and Make: Trigonometry. AFAIK, nobody has tried to do create physical sliders in their 3DP objects; that's certainly doable. If you're really interested in 3D visualizations, I strongly suggest checking out these books and 3DP the objects that those books use.
|
|
I also wanted to address Artur's question about @ vs. @* briefly. It's true that in some contexts they are the same:
f@*g@x === f@g@x === f[g[x]]
but this isn't really the point of Composition /@* . The real use of this (in my experience) is chaining functions together for use in Map or Apply . Consider a basic example:
In[716]:= N@*Mean /@ {{1, 2, 4}, {4, 8, 9}}
Out[716]= {2.33333, 7.}
Here, the @* lets you write a "single composite object" which is the composition of N and Mean . This composition function is then what is mapped across the lists. Simply using @ doesn't do this:
In[715]:= N@Mean /@ {{1, 2, 4}, {4, 8, 9}}
Out[715]= {7/3, 7}
Why? What's happening—visible through Trace , which I'm going to check after I type this side note to confirm my Vibes (they were correct)—is that N@Mean gets evaluated first, and N acting on Mean just provides Mean because there's nothing there to make numeric. So the idea is:
N@Mean /@ {{1, 2, 4}, {4, 8, 9}} = N[Mean] /@ {{1, 2, 4}, {4, 8, 9}} === Mean /@ {{1, 2, 4}, {4, 8, 9}} === {Mean@{1, 2, 4j}, Mean@{4, 8, 9}}
whereas
N@*Mean /@ {{1, 2, 4}, {4, 8, 9}} === {N@*Mean@{1, 2, 4j}], N@Mean@{4, 8, 9}} === {N@Mean@{1, 2, 4j}], N@Mean@{4, 8, 9}}
When composing functions, that's what you want. It can be really useful! Take the example from Good Coding Practices:
Framed@*Highlighted /@ {1, 2, 3} (* Unclear *)
(Framed@*Highlighted) /@ {1, 2, 3} (* Clearer *)
Map[Framed[Highlighted[#]] &, {1, 2, 3}] (* Clearest *)
You could rightfully argue that the first one is unclear, but if you understand how @* works it's very clear and very concise and very easy to write. You're taking the composed operation of "highlighting and then framing" and mapping it across the list {1,2,3} . It doesn't get better than that!
|
|
The email announcing the recording availability didn't send me to the recording, just to the materials folder (no video there). Also, there was a link to the Quiz, which I'm hesitant to try without watching what went on today. Help?
|
|
The e-mail announcing the availability of the recording of today's session was sent out at ~15:50 Eastern Standard Time today by the "Wolfram U Team". The subject is: "Recording available: Interfaces and Deployment". Search for "Wolfram U Team" in your inbox. The recording is accessed by clicking the "Watch The Recording" button in that e-mail. I called up the video; it is indeed today's recording. --phil
|
|
I did NOT receive this email.
|
|
Please contact our staff at wolfram-u@wolfram.com if you need assistance with webinar email notifications from bigmarker.com. This is the mechanism that is used to send Daily Study Group reminders and recording notifications.
|
|
Jamie, it would be cool if Wolfram Research could maintain a list of those BigMarker video archive links for each user in a particular WSG and have them accessible through a Wolfram-U portal in the Wolfram Cloud. All of the user's information for that particular WSG would be stored there. That would provide a reliable mechanism for all users to have the URLs -- and not worry about losing an e-mail through spam filters, force majeure, or whatever. It would also function as a beautiful professional archive for students to reference those training materials in the future. It would be an engaging example for how users can set up small programs establishing highly accessible live data using the Wolfram Language for their own customers. There's an expense setting this up, but a payout in reducing the day-to-day customer support and customer satisfaction. I bet there are staffers who could implement this as a one-liner. ;)
|
|
@Phil Earnhardt, I really like this idea! We have, in fact, had brainstorming sessions about building a Wolfram U portal that would help to archive links to past sessions and courses, certifications, and other useful information. It's good to be reminded there is interest out there. Thanks!
|
|
Well, good. The really interesting thing for me is having a cloud app that Wolfram U users would regularly be using -- and having some sense of what they could [cloud] deploy for themselves. One of the amazing bits of code that Wolfram U has is the grading engine for the Elementary Introduction to the Wolfram Language course. Anyone who goes through that course without being amazed what the grading engine is doing is just not conscious! Like many, It's tricky: you must have answers that are being produced computationally, but the implementors could not have anticipated everything users could possibly do. I found myself tweaking my answers -- just to see what the engine would judge as "correct" or "incorrect". IMHO, the only shortcoming with the EIWL grading engine is that the source code is not available. If/when you do this project, please design and implement it with the intention of making the Wolfram Language Notebook source publicly available. Students regularly using it should be curious about its implementation. And people will want to borrow/modify it for their own use; that's what you want. You may even want to do a BigMarker presentation where you walk through the source and explain what/why you do things (both for functionality and for code efficiency).
|
|
Trying to understand what Trace is telling me here. I have your words but still do not quite follow. Is it possible to step through this?
Attachments:
|
|
Hi Arben; Last week you showed an example of Function[] used with a variable as well as a #. Was it your intention to compare a prime function and a non-prime function or a prime function using a # compared to another prime function using a name? Thanks, Mitch Sandlin
|
|
Hey Mitch—"pure" function! But the idea was primarily just to show the "spectrum" from a full, named function with named variables down to a function with no name and whose variables were unnamed. Function of any kind is technically a pure/anonymous function, even if you provide "dummy variable" names for the inputs just like you would in a definition like myNameFunc[x_]:=... . The progression I have in mind is:
mySineAdder[num_]:=num+Sin[num]
Function[num,num+Sin[num]]
Function[#+Sin[#]]
#+Sin[#]&
The first function is a named ("nonymous", you could say, had history taken a different turn). The last three are pure or "anonymous" functions.
|
|
Hi Arben and all, I have a question about the last lesson about complexity time on function definition.
I have done this notebook and I want to know if there is a simpler complexity way to code the problem.
PLEASE SEE THE NOTEBOOK ATTACHED TO THIS COMMENT
Thanks Mauro
Attachments:
|
|
Hey Mauro—while I could probably figure this out if I sat and looked at it for a bit of time, I think I need to set the precedent that I can't take arbitrary code and rewrite it for you. However, what I am happy to do is to take an explanation of what your code is actually doing, with some examples, and tell you how I'd write a function that performs the operation in question.
|
|
Ok, Arben.
I think to have understood where I have made a mistake. It's very fuzzy, how speak with someone change our prospective, by only to expose the problem.
Thanks
Mauro
|
|
I understand—trying to figure out how to frame and phrase the problem to somebody else is often half the battle!
|
|
Hey Arben, In the Friday lecture you did a quick and dirty example of error trapping:
polygonMaker[n_Integer ] := Graphics[{Red, RegularPolygon[n]}]
Then you added a new statement in real time in your Notebook
polygonMaker[___] := "please enter a digit"
I thought basically the three dashes stand for "anything". But it seems in this context they stand for "anything else". I don't understand the precedence here. How did "else" get implied? I would have thought it redefined the function polygonMaker to always say "please enter a digit" from now on, regardless of the argument. What happened here?
|
|
I believe this is how it works: polygonMaker had two definitions entered into the database. When the function is called, the first version entered is called first, but if the type of the input type isn't an integer, then the next definition is called, which does have a response to anything else. The point is that the domain of polygonMaker was extended by adding that second step, but that extension is only checked when needed.(Technically it would be better for polygonMaker to catch integers less than three) Here's another example to ponder (entered in successive cells).
f[x_Integer] := x*1.0
f[x_Real] := IntegerPart[x]
f[3]
Out[187]= 3.
f[3.0]. (* the first version can't be applied to 3.0 so the second version is called *)
Out[188]= 3
|
|
This is basically it—there are two definitions here, and if one doesn't fit it will try the other. Still, Carl's question of precedence is valid, because ___ really means anything given that it's "zero or more things". The answer is: precedence is given in order from most to least specific definitions.
|
|
I had not picked up on that nuance even though I have used it (subconsciously?) as in the examples on recursion. I had not formally articulated in my head. WL does not pay attention to the sequence of definitions in code first, but yes to the hierarchy of precedence, which of course it does. Particular takes precedence over global. It's a grammar thing. But if definitions have equal precedence, then it picks the most recent one. (Correct?)
|
|
The documentation page linked by Rohit has this to say:
In the factorial function example used above, it is clear which rule is more general. Often, however, there is no definite ordering in generality of the rules you give. In such cases, the Wolfram System simply tries the rules in the order you give them.
You can check the order that definitions are stored—and tried—by evaluating ?func . (The fact that I had to check the documentation to be sure about this case should tell you something about its relative frequency, I hope!)
|
|
I wonder why the /@ stayed pupleRed in the last example of "Good Coding practices" (12. Pure Functions).
See attached screenshot
Attachments:
|
|
The spaces are really just a visual choice made by some programmers—I tend not to use them, and it shouldn't have this effect. I'll try to remember to check the full cell expression after today's class and see if I can figure out what's going on—if you look at the recording, you may note that I didn't expect that to look like that and am messing with it a little to investigate! EDIT: Yeah, it's just written into the cell manually that that should have a particular background color. If you start typing into that space/editing it, you'll retain the color choice.
|
|
Hi Arben,
I do not understand what you mean by your last lines -after the EDIT: I want to use different text colors for the comments in one cell. But of course still bracketet by (.........) to indicate that it is a comment.
As some comments are temporarely (like (* FIX this later *) and other comments are permament, I would like different colors for the different kind of comments.
As everything is adjustable in Mathematica, I would be surprised if this is not possible.
Thanks, Bert
|
|
In that particular context, I meant that if you press (on mac) cmd + shift + e to see the full cell expression, you could see that the color was "baked in" there. I'd generally recommend only using this for clever little modifications, not as a "primary" means to do things (generally). But it can often provide some insight. As for coloring comments, I recommend just using the Style menu. (Maybe we already dismissed this for some reason, but if so I don't remember!)
|
|
What I discovered on the MAC is that if you highlight just the text in the comment, not the (* *) at the beginning and the end of the comment, you can then go to the FORMAT drop down menu and select "Text Color". That will change only the color of the comment you are highlighting.
|
|
I don't see an option to start a new Topic, so I just reply.
I just saw Ahmed Elbanna's post, 4 days ago, and I agree :-) Great webinars series. Arben is the absolute BEST presenter I have seen in all the webinars I have already watched. He does it just right on every level and in every detail.
Arben, you're a fantastic teacher. You opened my eyes & understanding to new levels in things I already knew.
I hope you'll be doing much more presentations. My question : Is there a way to change the default color of a comment (* Comment *)?
I can change the Size, Face, but not the color. This would be really convienient as to make an easy distinction between comments :
* Explaining the code and function
* Things that need repair, seriously
* Things that need brushing up or speed enhancement
* Alternative versions
* Spots in the code that need extensions in the future
* Etc. It would really be great to have this color function.
I know that I could do this with 'text' parts, but that will break the possibility to run the complete code with one Shift+ Enter.
|
|
Re. changing the default color of comments look at Preferences / Appearance 
|
|
Great course! (As usual from Wolfram). I really like the overall structure, the examples, the smaller checkpoints and the exercises at the end of each day. Here are some improvements for the 5th exercise of Day 4
txt = ExampleData[{"Text", "DeclarationOfIndependence"}]
(LetterCounts[txt, 2] // ReverseSort)[[;; 20]]
The solution provided uses Take[.., 20], this takes the first 20 elements. Not the 20 most frequent ones.
Adding ReverseSort post fix style, sorts the association biggest->smallest.
Similar with the second part.
((WordCounts[txt // DeleteStopwords] // ReverseSort))[[;; 20]]
|
|
Let me know if I have this wrong, but I believe that LetterCounts is always automatically reverse-sorted by value and thus the first n elements—as taken by Take , for example—should always be the 20 most frequent elements. Do you have a counterexample in mind? (Or perhaps this behavior was different on an older version, perhaps pre-13 or even pre-12?) EDIT: Oh, I see—there's an issue with the version where stopwords are deleted. Thanks for pointing that out; I'll fix it!
|
|
Arben, First thank you for teaching this class. This has been very helpful. I am running into some unexpected behavior. I just downloaded Version 14, and when I do TreeForm of a list I get: 
but when I do the same thing using Plus, I get: 
I was expecting to get the same thing but with List replaced with Plus. I am a bit puzzled. Many thanks for your help.
Michael O'Connor
|
|
Hey Michael! The reason this happens is the order of evaluation. I have two suggestions for you to try which I think will clarify this behavior:
Trace[TreeForm[Plus[1,2]]]
TreeForm[List[a,b]] (=== TreeForm[{a,b}] )
Let me know if this illuminates the difference for you.
|
|
Also, Plus has the NumericFunction attribute whereas List does not.
Thus one sees the following behavior from TreeForm: 
|
|
Arben, this does help! Thank you very much!!!
|
|
From yesterday's lesson, does anyone understand why
larger[x_, y_] := If[x > y, x, y];
Fold[larger, {3, 1, 2, 6, 5}]
returns
larger[larger[larger[larger[3, 1], 2], 6], 5]
and not 6?
|
|
As do I. Coe, you might have given larger an incorrect definition that hasn't been overwritten for one reason or another—try restarting your kernel and running these two lines again? (Re: the new comment—the semicolon is fine. It's not necessary for SetDelayed definitions since the evaluation is, as claimed, delayed!)
|
|
Try removing the semicolon
|
|
map mystery Can someone explain what is going on in the expressions below the tree, or would this be too advanced for the level of this course (which, if it is, is OK with me)? (See attached png file)
Attachments:
|
|
Hey Steven—I think that these three points in concert are enough to answer your question, but please let me know if they don't:
Map[f,expr,n] maps f to expr down to level n
Map[f,expr,{n}] maps f to expr only at level n
Map[f,x] = x for AtomQ[x]==True (cf. our discussion yesterday: Map goes into the inside of an expression to work on its parts; atoms don't have parts so Map has nowhere to put the f —this could have been designed to produce an error message, but the decision was to have Map function such that if it can't map a function f somewhere, it just returns the object onto which f was asked to be mapped)
|
|
Hey Arben, Loving your class. Got a little exercise: The transfer function of non linear power amplifiers produces inter-modulation products between the tones at their inputs. If the transfer function is expressed as a simple 5th order odd polynomial, and the input x is made of two sine waves at frequencies w1 and w2, you can easily find the mess that shows up at the output. It includes 3rd and 5th order inter-modulation products around the two tones, 3rd and 5th harmonics, and inter-modulation products around the harmonics. In RF systems we use band-pass filters to select only the fundamental tones and those tones around the fundamentals w1 and w2 (usually assumed to be closely spaced compared to the frequencies of the harmonics... Although audio systems will not be so cooperative.) I've been playing around with some of the concepts I thought I was learning to take the output and literally select them, but it's not working yet. In the past I've just given up and brute forced it (yuk). This time round I'd like to learn how to do it right...help?
Attachments:
|
|
We really do abhor a brute force solution. This is a fun little question; please see embedded response!
PLEASE SEE THE NOTEBOOK ATTACHED TO THIS COMMENT
Attachments:
|
|
Thank you, Arben!!! That's a really neat approach. Had not yet thought along the path of creating a list of all the terms. But entirely consistent with thinking about the heads and changing them. That's a powerful analytical tool. Your solution has a lot of pedagogical value. I am going to be staring at it a bit. If you are on a roll, I've got another one coming as soon as I can figure out how to ask it properly. Let me take a crack and if it needs more let me know:
It has to do with a problem in FM theory, where recognizing that
Cos (B Sin [w t])
can be expanded as a Fourier series whose coefficients are an ordinary Bessel Function of the first kind = Jo(B) + 2 Sum (J2n(B) Cos (2 n w t) ) Then you have to truncate the series to get the coefficients of interest. There is a similar expansion for Sin(B Sin (w t).
You can sample an FM signal and do an FFT and just see the spectrum, but recognizing the Bessel Function behavior provides an intuitive understanding of FM theory (bandwidth, mod index, S/N properties etc) that even when FM was really popular few people grasped. Now it's beginning to be a lost art.
What I never figured out how to do was use WL pattern matching and mapping tools to "recognize" and derive this classical solution. It has other analytical advantages for other problems too.
|
|
I really strive to provide pedagogically useful answers, so I appreciate it :). If I'm reading your (original) post correctly, you could also do pattern-matching or selection by going directly into the cosine terms, extracting the coefficients of the omegas with CoefficientList and grabbing only those cosine terms for which the absolute value of the difference is 1. This would make it so you don't even have to generate the desiredHarmonics list, if that's indeed what you want. As for your new question, some more information would indeed be helpful. It's been a long time since I've dealt with this sort of thing, and certainly I've never approached it from the perspective of signal analysis and decomposition. But, fundamentally, you could write the same kind of thing as above with Cases , specifically recalling that Cases allows not just for pattern-matching but for term-rewriting too. So you could do something like:
Cases[expr,Cos[B___ Sin[ω t]]:>(full or truncated B-dependent sum here)]
This would extract all of the relevant cosine terms and rewrite them; you could update the rule to include both sine and cosine terms but I'm forgetting the way to do that right now. You could do something similar to the previous case and just extract all cosine or sine terms that have the right form, then use a simple /. to write a rule which appropriately converts the cosines and sines to their sum forms. You may also be interested in TruncateSum (new in 14), though this behavior was always manually implementable with a little elbow grease. Otherwise, if you have an exact worked example, I'm pretty sure I could write something up reasonably quickly.
|
|
Thanks Arben, I will get back to you on that FM question. I have to find my notes on when I last tried to do it. "If I'm reading your (original) post correctly, you could also do pattern-matching or selection by going directly into the cosine terms, extracting the coefficients of the omegas with CoefficientList and grabbing only those cosine terms for which the absolute value of the difference is 1" That sounds kinda like what I was originally trying to do but unsuccessfully. Could you show an example?
|
|
Let's see:
PLEASE SEE THE NOTEBOOK ATTACHED TO THIS COMMENT
EDIT: Really better just to use Coefficient . I don't like CoefficientList anymore; it's dead to me. So this is probably the most efficiently and extensibly you could write it?
Cases[yexp,
c___*Cos[arg_] /;
Abs@Total@Coefficient[arg, {ω1, ω2}] == 1]
Attachments:
|
|
Delicious!!! Once again a pedagogical Rosetta Stone.
Thank you ,
Carl
|
|
Hey everyone, care to take a stab at explaining why:
Total[{{a, b, c}, {u, v, w}, {x, y, z}}]
returns
{a + u + x, b + v + y, c + w + z} (*One of our Day 4 "Check Your Understanding" questions*)
I've looked at the documentation for "Total" and still can't figure out how this result is obtained.
Thanks in advance,
|
|
Hey Coe, I can explain this. Total is documented to take the elements of a list and add them together. In other words:
Total[{a,b,c,...}] === Plus@@{a,b,c,...} === Plus[a,b,c,...]
In standard notation, that means that Total[{a,b,c,...}] just evaluates to a+b+c+... . Nothing too surprising here, I think. The misunderstanding likely comes from two places. Since Wolfram Language is fully symbolic by default, we never said what a , b , c and so on might be. They don't need to be reals or integers or even numbers—in fact, try this for me:
randomImages=Table[RandomImage[{0, 1}, {25, 25}], {2}]
Total@randomImages
If there is a sense in which the arguments inside the List fed to Total can be added, then Total will add them because it is very literally just performing the pattern-matching term-rewriting transformation rule I expressed above. Now that we know what Total does, if we want to understand the output of Total[{{a, b, c}, {u, v, w}, {x, y, z}}] , we need to ask: what does Plus do when fed multiple List objects? You can try this out manually, but that's basically just rewriting the thing that we're not understanding in the first place. Instead, you might try Attributes[Plus] . You get back several attributes, but the important one here is Listable . If you check the documentation for that, you'll see examples which basically replicate the behavior that prompted this question:
In[1]:= {a, b, c} + {x, y, z}
Out[1]= {a + x, b + y, c + z}
This is to say: Listable functions automatically thread over their arguments when those arguments are lists. Most built-in mathematics functions are listable, and this attribute allows for highly optimized code compared to looping or even mapping. In the case of Plus , this behavior also happens to correspond to the standard mathematical operation of addition acting on vectors, matrices, and tensors more generally. After all, if you have the vectors a, b, and c, you find their sum by element-wise addition, right? The same is true for matrices and so on. (And in fact, people are often lazy and will "add" a scalar to a vector when what they really mean is that they want to add a constant vector to a vector. For example, somebody might say x = <1,2,3>, then say something like x + 1, when really they mean x + <1,1,1>. This is also automatically handled by Listable ; feel free to evaluate {a,b,c}+1 and see the result, or even {{a,b},{c,d}}+1 .)
|
|
Arben - Thank you very much for the detailed explanation. I am finding this material somewhat difficult but rich and rewarding when something sticks.
|
|
Tree walking - inconsistency or design Given some algebraic expression y, I can do y[[3,2,5,1,..]] to walk the tree (or the full form) to a particular node.I can also do y[[0]] which is the same as y//Head. However, y[[0,2]], for example, is an error in my notebook, though presumably it should be the same as y[[2]]. This seems to me an inconsistency, but perhaps it is that way on purpose???? (In y[[3,2,5,1,..]], presumably the "0" is implicit.) This is probably not a big deal, but I am bothered by stuff like this - a sort-of reflection edge condition that doesn't seem sensible.
|
|
I don't think that this is an inconsistency: if you do extract a head with [[0]] , that head does not have some internal structure that you can probe by asking to get its parts. What is the second part of Graphics ?
|
|
It seems to me the Head is just a node. I don't understand why it should be different from any other node. If it doesn't have a structure, why should any other node have a structure? I suppose there is something in the engine which interprets the head node differently from other nodes.
|
|
I think I see what you mean; I think that that's fair enough if you're thinking about it in terms of TreeForm . The discrepancy, such as it is, exists because technically Part is always "reaching into" an expression (cf. the reason you can't [""] use Part on atoms is because they don't have an "inside" to reach into). That is: whenever you say expr[[n]] , you are going into expr and extracting something. If you have not just a single n , but exprp[[m,n,...]] then the number of elements in that sequence specifies the Depth at which you are accessing the structure of expr . The issue here is that expr[[0]] does indeed not work like this: because indexing in Wolfram Language starts at 1 , this is not "getting a part" of expr in the same sense that expr[[n]] for n≥1 is, but is "special case", manually-implemented extra behavior. I do see why one might consider this inconsistent, but my personal sense is that [[0]] is simply used as a convenient syntax shortcut for Head@ . If we didn't have it, the behavior of Part would indeed be more consistent, but it would also be less functional for some particular uses... my perhaps-frustrating advice is to do a bit of compartmentalization about the meaning of Part , here. We're already doing that when using Part on SparseArray or Dataset atoms, so why not add one more case where Part is doing something which is maybe a little bit misleading... Finally, I do want to clarify something: because this [[0]] is a special behavior which does not give you the 0th part in the technical sense (as there is no 0th part in a language which indexes from 1), it is not the case that there is an implicit 0 which starts off any Part sequence. Moreover, there's nothing in any given expr that you cannot access because of this: the entirety of the internal structure of expr (if it has any) is accessible without making any reference to any 0th part. It's just that if you would like to get not the internal structure, but the thing that wraps around that internal structure—which in the strict sense is not a part—then we allow you to do that with Part[expr,0] as a convenience. The succinct version is maybe:
Part is really only intended to talk about the parts of a compound expression, and the "parts" of an expression are always internal to the expression.
- Because you could already access everything about an expression but its head with
Part , we added a special case of asking for """the zeroth part""" so that you could get that last bit of information without having to leave Part -world.
|
|
Thanks. That's really helpful.
|
|
In the "Check Your Understanding" exercise for pure functions we are told that Function[u, 3+#][x] is the correct syntax for returning 3+x given x as an argument. I think that's incorrect (?)
|
|
Good catch! I've fixed this in our repo and it will be fixed in our next deployment.
|
|
I asked in the BigMarker Q&A panel how to upload a WL Notebook to my Wolfram Cloud account. The reply was to use the "upload" button in the upper right corner of the Wolfram Cloud window. This doesn't work; I get the error message, "To access this feature, subscribe to a plan." Apparently, the Basic plan isn't good enough. I can upload files through Mathematica on another machine through the File->Save to Cloud function. I don't understand why that works but simply doing an "upload" in cloud does not. Is there a good reason for keeping a random user from uploading any notebook to a Wolfram Cloud account through the web? If not, please file this as a bug. One note for the staff answering questions: when they are answering a question like this, they should try to perform the function with the same level of privilege/access as a normal customer. In this case, the Wolfram Cloud "upload" function should have been tried on a Basic plan.
|
|
Hello Phil, Thank you for letting me know. I apologize for the confusion created. Upon a detailed look, the behavior described seems to be related to the fact that Wolfram Cloud and Wolfram Desktop are two separate products. The basic plan for Cloud grants users the basic functionalities needed for a smooth Desktop operation, but it does not grant access to the Wolfram Cloud as a product in and of itself. Basic Plan restrictions This is why the direct dynamic interaction within Wolfram Cloud is not available but the use of CloudPublish from Desktop, either programmatically or through the menu tool, works as expected. I will try to improve my Q&A support with your feedback. I have already setup a basic account for testing of future questions. Thank you!
|
|
Hi Everybody! I would like to produce documents effectively (so programmatically) and I need to find help about producing cells, sometimes cells within cells (within cells?). Can anybody give a good reference? Such things as TextData, BoxData, ToBoxes, ToString and similar.
|
|
Yes, I also found that I couldn't use the code output by those boxes in situ. Entering it into a new code cell works fine.
|
|
I'd highly recommend Professor Richard J. Gaylord's Wolfram Language Fundamentals
|
|
Hate to redundant, I still can't get by this. If this is a real error, other errors I get may be me or Mathematica - can't tell. Btw, $Version returns: 14.0.0 for Mac OS X ARM (64-bit) (December 13, 2023).

|
|
Please see the answers downthread—the easiest way I know to explain this is that if you say ax , how is Wolfram Language to know that you actually, truly, really meant a*x ? It can't. If you were to type myVar^2 , you ostensibly would not expect to get m^2 * y^2 * V^2 * a^2 * r^2 , so why expect differently for ax^2 ? (Since tone is never conveyed well over text, I want to be clear that the intended tone here is "Socratic" rather than "snippy" ;).)
|
|
ax is on variable not two variables
a * x is and expression equal to a space x
|
|
I think the best way to see what is going on, on your own machine, is to look at y//FullForm and z//FullForm. They are quite different. 
However if you insert a space between a and x in your expression for z, then y and z should be the same. [If you are somehow stripping out spaces, then that will cause you problems. Mathematica really uses the spaces as Arben says. I am already finding that when I am getting odd results, using FullForm, TreeForm etc can make things clearer.
|
|
Perfect. I get it, thank you.
|
|
While working with the exercises for Day 3 (Syntax and Expressions), I got the following error message while attempting Exercise 4 (ListLinePlot for airline passenger data), namely
"An improperly formatted option was encountered. The left-hand side of the option was not a symbol or string*
My solution(s) worked fine initially, but then went wonky all of sudden. In fact every plot in the notebook threw the same error message, whether options were specified or not. (Also all of the dynamic Hints and Solutions boxes disappeared, but that's not my main concern right now). Please see attached notebook..
Attachments:
|
|
Hi Michael—I think the issue comes from the formatting that this notebook has for that ListLinePlot input. Ideally, it would just be an input... but when you click into it, you can see that there's a kind of yellow box around it. Basically, this is a text cell formatted as input and so it won't evaluate correctly, if we're seeing the same thing. (I think your specific errors with respect to Dynamic elements here are kernel-specific and thus not "carried with" the notebook that you uploaded when I open it on my end, so I can't see for sure what your issue was.) if you just start typing ListLinePlot in a new cell, you should be able to plot the data without issue. I think what's happening is that on our end, making the Hint/Solution buttons does something unfortunate to the formatting of code blocks that we had intended for you to type into. I'll look into this with our team.
|
|
Arben, Thanks, that makes a lot of sense since both errors occurred at the same time. I'll try out your suggestions and see what happens.
|
|
Arben, Just to let you know I opened this notebook the next day in order to try your suggestions, and it had healed itself overnight. One of those situations you're glad it's fixed without any effort, but not quite sure why. Anyway, all is good for now, and everything is working again as expected. I even entered some new comments and code into the notebook, and nothing seemed to upset it again. Fingers crossed! :<) :<)
|
|
In[84]:= Clear[x, y, a, b, c]
In[85]:= y = a x^2 + b x + c
Out[85]= c + b x + a x^2
In[86]:= Expand[y^2]
Out[86]= c^2 + 2 b c x + b^2 x^2 + 2 a c x^2 + 2 a b x^3 + a^2 x^4
system: Apple M2 Ultra, 14.3 (23D56)
Mathematica: 14.0.0.0 Mac OS X ARM (64-bit)
|
|
I know you touched on this, but in exp = 1 + x^2, exp[[2, 1]] returns x, yet exp[[1, 1]] is longer than the depth of the object, why again?
|
|
exp[[2, 2]] returns 2, the second part of the second part, I'd expect exp[[1, 1]] to return the first and only part of the first.
|
|
AtomQ[#] & /@ {exp[[1]], exp[[2]]} returns {True, False}, and Atoms don't have parts (errrrrrr... it's counterintuitive).
|
|
...and this can be seen: AtomQ[exp[[1]]] returns true.
|
|
Yeah, it's just atoms have parts as far as atoms are concerned, as apposed to atomic expressions. The same signifier ("atom") points to different signified concepts depending on the context, hence counterintuitive. Essentially, atomic parts are not the same in the case of the fundamental concept in chemistry and physics and atomic expressions and therefore not covered by Part in the normative sense. So an error message is returned.
|
|
There are sub-atomic parts
|
|
Understanding this helps in navigating subjects that cross disciplinary boundaries.
- GPT4
|
|
Nice! I hadn't thought (until today!) about the derivation of the word atom. So, 'tom' as in 'tomography'.
|
|
Yes, the very same! It's from τόμος, which I think is from Ï„Îμνω, which is something like "to cut/slice/section/portion".
|
|
The notion of uncuttable is really helpful, thank you. I’ve now learnt to turn to inbuilt functions in order to better understand what’s going on and just the idea of syntactic convenience is helpful in getting over what at times has felt like contradictions in terms. I remember Prof Richard J. Gaylord saying once that Wolfram, at times, behaves strange, and never quite knew what was meant by that (likely the pitfalls of intuition).
|
|
I think the apparent confusion regarding the word atom is as a result of an error in the evolution of our scientific knowledge. It is only relatively recently that we discovered that 'atoms' of, say, radium are not really atoms in the logical sense of the word. Then we repeated the mistake, calling some of the sub-atomic bits "fundamental" only to find... In a parallel universe where the Wolfram language was developed in 1880, the concepts of atoms in Mathematica and Chemistry would have been consistent. Although some physicists maintained that the atoms of the chemical elements were fictional conveniences for the sake of calculation and that, if they even existed they would be too small to ever be known. Then came 1905 and Einstein's analysis of Brownian motion.
|
|
One thing that really attracted me to Wolfram was how the expressions in a book I picked up published in 1988 still computed. Thankful, in this universe there is forward compatibility, even amongst changes in scientific knowledge.
|
|
Although Show[Graphics3D[Stellate[ Icosahedron[ ]]]] wasn't forward compatible.
|
|
Heh, it's true :). At least in this case it's been superseded by something simpler and clearer!
|
|
I can heartily recommend this. While I am in no position to judge Wolfram's contribution to Physics, the ideas are fascinating and are something I would like to pursue. If I am hearing him correctly, he is attempting to make sense of Physics by looking at it as a system that is computable by the application of rules for re-writing. He seems to be saying the system evolves what look like small black holes and "elementary" particles from vacuum energy. Of course he is talking to a professional physicist here so we hear him respond to some good questions. I am stricken by the similarity of the method Wolfram is proposing and the spirit of the the approach we seem to be taking in grappling with Mathematica. Very stimulating! https://www.youtube.com/live/ITJ3AF3TK5M?si=rECCBuBAAVWa_Im4
|
|
Steven/Arben - I too am getting the INCORRECT result. I am also running Mathematica 14.0.0 on Mac silicon. (This might also explain some of the results I have been getting!)
I create a notebook and set y = ax^2 + bx + c. I then try Expand[y^2] and get the following:
ax^4 + 2 ax^2 bx + bx^2 + 2 ax^2 c + 2 bx c + c^2
I have attached my notebook and an image making it clear what element is incorrect in Mathematica's answer.
Attachments:
|
|
PROBLEM PROBLEM PROBLEM When I create a notebook and try y = ax^2 + bx + c, then Expand[y^2] gives ax^4 + 2 ax^2 bx + bx^2 + 2 ax^2 c + 2 bx c + c^2 in my notebook, which is incorrect, while yours has c^2 + 2 b c x + b^2 x^2 + 2 a c x^2 + 2 a b x^3 + a^2 x^4 which is correct. I'm, using Mathematica 14.0.0 on Mac silicon. Here is my notebook
|
|
More info:
When I do "y = ax^2 + bx + c", with explicit asterisk, then Expand[y^2] is correct
c^2 + 2 b c x + b^2 x^2 + 2 a c x^2 + 2 a b x^3 + a^2 x^4 Note: The preview removes the explicit asterisks. What works is
y = a asterisk x^2 + b asterisk x + c
|
|
Write "a x" with a space between a and x. Mathematica interprets the space as a multiplication.
|
|
Addendum to Lara's explanation: "ax" is read as one symbol, as opposed to "a x" which is read (in the example case) as two distinct symbols of a numeric type, so the space is interpreted by Mathematica as an implied multiplication.
|
|
I don't believe this is a space issue. The notebook shows input (w/o spaces) and the incorrect output.
|
|
Hey Coe—I'm not sure what you mean. The attached notebook is missing the spaces between the coefficients and thus produces the incorrect output. You want:
y=a x^2+b x+c
or, explicitly:
y=a*x^2+b*x+c
in order to get the correct polynomial expansion. @ Steve, you can type your code between two backticks to prevent it from formatting via markdown, which is why the asterisks are being used for formatting rather than displaying.
|
|
When I enter everything without spaces I get the wrong answer. When I enter WITH explicit asterisks, I get the right solution. The attached image shows what is entered and the result.
Attachments:
|
|
Steven - I get the correct answer when using explicit multiplication:
y = a*x^2 + b*x + c
Why is this? Arben?
|
|
To be absolutely clear: this is equivalent to asking why var^2 does not return v^2 a^2 r^2 . If you don't type a space or an asterisk between two letters, there's no way for the system to know that you're talking about two separate symbols.
|
|
Bang head with hand. I forgot. Thanks.
|
|
It can happen even after a decade of using the language—I was once thwarted for an entire day by an errant curly/("""smart""") quote breaking a string expression when I first start working here!
|
|
Another way of saying the same thing: Mathematica is taking ax^2 to mean (ax)^2. This can be seen by asking for the FullForm. In terms of today's lesson: AtomQ[ax] returns True , AtomQ[a x] returns False.
|
|
Hi Arben, Would please clarify the following terms: vector, array, matrix, expression?
And regarding the docs, what's the difference between options and properties in a function?
|
|
When I'm using those terms, I mean:
- Vector: something that you can describe with 1 index. It could have a length of 2 or a million, but you could get any singular element out of it by doing
vec[[n]] .
- Matrix: something that needs two indices to get any individual elements from: say, the element at the first row and third column could be accessed with
mat[[1,3]] .
- Tensor: generic term for anything where you'd need more indices to describe the position of a single element. Note that this is not really an appropriate definition in the physics sense, but I'm being a little loose with it. You can think of them as the general case of the special "one-index" and "two-index" cases of "vector" and "matrix", respectively.
- Expression: any sort of singular "thing" in Wolfram Language—that is, anything that's not a sequence like
a,b . a is an expression, Plot[x,{x,0,5}] is an expression, and so on.
You can see more of the fun of conflicting definitions here.
|
|
I thought I understood this material during the lecture; most things made sense. Some parts of Problem 1 however just don't seem right. For example, why does pat3 give the following result?
exprs = {1, h[], h[a], h[b], h[a, b], h[a, a], h[a, b, c], g[h[a, b]]}
pat3 = x_
Cases[ exprs, pat3]
{1, h[], h[a], h[b], h[a, b], h[a, a], h[a, b, c], g[h[a, b]]}
I see no way to get this result. Thanks in advance,
|
|
pat3 is x_ , which means "any one thing—call it x ." Every element of exprs is just a single thing, so they all match. Because we're not using that x anywhere, this pattern is equivalent to just _ , i.e. "any one thing".
We might see a named pattern like x_ in a standard function definition:
f[x_]:=x^3
The x on the LHS has nothing to do implicitly with the "any one thing" denoted by the _ . The x is just a dummy name that we give to that one thing (the one thing that appears in f 's brackets) so that we can refer to it on the RHS. Consider the example:
f[x_]:=5
There's no mention of x on the RHS, so it's pointless to even name it on the LHS (in some sense.) It would be exactly the same to instead say:
f[_]:=5
The point is that "f of any one thing" should be 5 . We don't care about the input here, so why bother to name it if we're never going to use it? In this sense, we are saying that f is a transformation rule that takes anything of the form "f of any one input, and I don't care what that input is" and returns 5 .
|
|
My apologies folks, I mis-wrote the equality that I am asking about. Again -
In today's post-lecture questions "pat2 = _h" Case tells me that pat2 matches the following elements in exprs:
{h[], h[a], h[b], h[a, b], h[a, a], h[a, b, c]}
Does this mean that **pat2 = _h = h_**? It seems like it, but this seems odd to me in that we are PATTERN MATCHING and, it seems to me, elements in one order should not necessarily be equivalent to elements in a different order.
Comment?
|
|
pat2 is _h , which explicitly means: "any one thing with head h ". This is not the same as h_ , which means "any one thing—call it h ". It is (except for perhaps some pathological edge cases) the same as h[_] , which is "h of any one thing."
|
|
In today's post-lecture questions "pat2 = _h"
Case tells me that pat2 matches the following elements in exprs:
{h[], h[a], h[b], h[a, b], h[a, a], h[a, b, c]}
Does this mean that pat2 = h = h? It seems like it, but this seems odd to me in that we are PATTERN MATCHING and, it seems to me, elements in one order should not necessarily be equivalent to elements in a different order. Comment?
|
|
question = "If Mathematica is a term rewriting system, when I write a programme in Mathematica, am I writing a term rewriting rule, and is the programme a function?"; If[question==={"yes", "yes"}, "At what point does a rule become a system?","Help!"]
|
|
Yes! The evaluation system is effectively a huge database of pattern-matching term-rewriting rules. For example, think about:
D[x^3,x]
We know that this is "the derivative of x cubed with respect to x", and we know that when we see this pattern—the derivative of x^n_ , if you will—that we should take the power, drop it to the front, and then subtract 1 from the power. The Wolfram system is effectively doing the same thing: it sees that something matches the pattern D[x^n_,x] and says what we do: "I know what to do when I see that: D[x_n,x] :> n*x^(n-1) and that's what's returned to us. When you write your own functions, you are effectively adding to this database of term-rewriting rules (and are often using those rules as foundations for your own definition). In this way, any program you write is just about matching patterns and transforming the appropriate ones into something new.
|
|
Wonderful explanation! I'm going to give this more thought. I'm trying to get my head around Wolfram engine.
|
|
Anyone grok this list operation: Alphabet[][[;; 10 ;; 4]]
I understand Alphabet[]
I understand Alphabet[] [[;;10]]
I understand Alphabet[] [[;;4]]
I do not grok what's happening when the 2nd and 3rd statements are combined. I thought the ";;" operation acted like a pipe. The solution {a, e, i} isn't what I think a pipe should give.
|
|
Hey Coe, could you be a little clearer in your description of your inputs, their actual outputs, and the outputs you would expect? In the meantime, let me explain the meaning of each line you've included here.
Alphabet[][[;;10;;4]]
This is equivalent to Alphabet[][[1;;10;;4]] . This means "starting with the list of all of the letters in the (Latin) alphabet, take the first through the tenth elements in steps of 4." I.e., that's elements 1,1+4,1+4,+4===1,5,9 . (You don't go to 13 since the initial list only has 10 elements.) And indeed, that's what this code does—cf. MapIndexed[#2[[1]] -> #1 &, Alphabet[]] or Thread[Range@26 -> Alphabet[]] to see it directly. Actually, I see what you were initially asking. I think the above sufficiently clarifies it, but "in order":
Alphabet[] provides a list containing the characters of the Latin alphabet
- Appending
[[;;10]] is the same as appending [[1;;10]] and is extracting the 1 st through 10 th parts of the list containing the alphabet
- Similarly, appending
[[;;4]] is equivalent to appending [[1;;4]] and is extracting the 1 st through 4 th parts of the list containing the alphabet
Doing [[a;;b;;c]] is not the same as doing [[a;;b]][[;;c]] . The "sandwich" construction specifically means "go from a to b in jumps of size c "; it's different from "chaining" ;; /Span commands through [[ ]] /Part .
|
|
Hello Coe! Arben's explanation made me want to see it in color. This is what came of it. I hope it helps.
PLEASE SEE THE NOTEBOOK ATTACHED TO THIS COMMENT
Have fun!
Attachments:
|
|
Thanks for teaching and I look forward to gaining new insight and learning the various facets of the Wolfram Language and learning to code with Mathematica. The course in this series labeled with #34 for the most part was attended, although completion of the course-work is latent. Hastily, without having differentiated or juxtaposed the two sets of files, I'm wondering about the development or difference thereof. Also, is this the appropriate place to provide commentary or share what you are learning or problems that you may be stuck on in the sense of posing a problem that is confounding? For the sake of convenience, I have the following two lines for reference with the time zone set to GMT-8 for current locale the default being +1 given the supposed original temporal datum or original time where it is that the Vatican City state is presently, as well as central Europe and Scandinavia. This is just for contrasting disparate times along the lines of DateObject[] and use of SolarTime[] and MoonPosition[] for scheduling, thinking with respect to calendrical arithmetic or geo-computation for arranging one's day according to a plan in the sense of avoiding scheduling conflicts and slotting time around attendance of the course.
Transpose@{Alphabet["Greek"][[1;;10]]//Capitalize,(QuantityMagnitude/@Table[(a-DateObject[List[1,1,11,0,0,0],"Instant","Gregorian",1.`]),{a,{DateObject[{2024,1,29,9,0,0}],DateObject[{2024,1,30,9,0,0}],DateObject[{2024,1,31,9,0,0}],DateObject[{2024,2,1,9,0,0}],DateObject[{2024,2,2,9,0,0}],DateObject[{2024,2,5,9,0,0}],DateObject[{2024,2,6,9,0,0}],DateObject[{2024,2,7,9,0,0}],DateObject[{2024,2,8,9,0,0}],DateObject[{2024,2,9,9,0,0}]}}])//Ceiling//FactorInteger}//Grid
and also
TableForm[Transpose[List[List["Lists and Associations","Assignments, Rules and Patterns","Syntax and Expressions","Writing a Program","Good Coding Practices","Interfaces and Deployment","Working with Data, Part I","Working with Data, Part II", "Developing Packages","Review Session"],List[DateObject[{2024,1,29,9,0,0},"Instant","Gregorian", -8.`],DateObject[{2024,1,30,9,0,0}, "Instant", "Gregorian", -8.`], DateObject[{2024,1,31,9,0,0}, "Instant","Gregorian",-8.`],DateObject[{2024,2,1,9,0,0},"Instant","Gregorian",-8.`],DateObject[{2024,2,2,9,0,0},"Instant","Gregorian",-8.`],DateObject[{2024,2,5,9,0,0},"Instant","Gregorian",-8.`],DateObject[{2024,2,6,9,0,0}, "Instant", "Gregorian", -8.`],DateObject[{2024,2,7,9,0,0}, "Instant", "Gregorian",-8.`],DateObject[{2024,2,8,9,0,0},"Instant","Gregorian",-8.`],DateObject[{2024,2,9,9,0,0}, "Instant","Gregorian", -8.`]]]]]
With respect to this is the question of how to seamlessly integrate sharing of snippets of code like this in and that within Wolfram|One this was drafted and then the sequence was right click the "cell object delineator" (For lack of the proper term, assuming that is the incorrect phrase or string for a potential association) and then through the "drop down menu" "Plain Text" was selected and then "Alt + Tab" to navigate to Notepad and then "Ctrl + V" in the window after left clicking and then copying again via the aforementioned technique and then tabbing or repeatedly using the "Alt + Tab" macro/technique or combined key-press selecting the Microsoft Edge window and then again (As with Notepad via Windows 11) left-clicking and then pasting or using the "Ctrl + V" key-combination after left-clicking. This is rather cumbersome and tedious in the sense of efficacy with respect to the users resource of time (Avoiding philosophical subtleties with respect to the complexity classes and dichotomy in the sense of Kolmogorov & also the power tower or sequential binary operation, to provide an errant opinion in the mode of assumption). Perhaps accessing this page from within the Mathematica console or the Wolfram|One program such as what was mentioned earlier with external APIs in some way navigating a directory safely and in a maximally efficient manner with respect to augmentations such as keypress (Again, lacking the lingo or appropriate terminology with respect to this programming language or the sequence of expressions in the sense of algorithm). One question is about accessing this course via BigMarker through a secure channel or learning about ports and other nuanced aspects in the sense of being conservative with data and being able to readily upload information through the WDF or contribute in real-time to the Wolfram Function Repository without removing attention from the lecture such as with alternate channels of data in the sense of active execution for formatting and the like. Hopefully, I can provide less loquacious or verbose inquiries, yet the actual procedure of the computer program (I assume algorithm is correct in the sense of encapsulating it lexically or calling it by one word, as I imagine that I may do if there is audio programming and "calling" the server/use of the kernel involves univocal definitions and sensitivity in terms of attenuation) is what I'm curious about and I've deviated from solving the puzzles or producing a solution set, to my own detriment. Given that so much time is spent with low-level calculations in Mathematica such as the above, a curiosity is with more compact functions such as with the pure function or defining the concept parametrically (Only having a vague notion of that at present, in the sense of a region that may be implicit, explicit, or parametric, according with abstract or universal geometry [rudimentary mathematical constructions and later demonstrations is a crucial project at present with developing thinking methodically or discerning the methodology, which I think that the Documentation Center does a good job of as it is worded, that I've noticed up until now, although one curiosity, further still, tangentially, is about the LinkSnooper and modifying the formatting with notebooks for stylesheets and whatnot. CloudDeploy[] was noted at 0713 0750 0203 and APIFunction[] on 0863 that date, although I currently lack knowledge of their utility with respect to rough outline of the aforementioned project, failin to attend/being truent for the course on May 16, 2023 on Programming Fundamentals. There is a wonder from 11439 about notation and Boolean Algebra with nn*ee, b^^nnnn, &&, ||, !, and <> about Element[] for the atomic expressions and use of Distributed[], UndirectedEdge[], DirectedEdge[] for Galois Theory (Which was, FiniteField[] and the related group theoretic constructs, experimental as of version 13.3.0) with there a curiosity about Polynomial Algebra and the S- and K-combinatorics with the Chief Executive Officer expounding work from December 1920 (Find WikipediaData@"Combinatory Logic" for a more concise elaboration) and use of bit-vectors in the aforementioned sense of a directory and efficacious navigation through WolframScript via the command line without a graphical interface. 738904.0199
|
|
Hey Arben, I've not used associations before and I am trying to imagine what is their superpower. I'm not really a software writer, I just play one when I'm trying to study or solve engineering problems. One idea that jumps off the page is using a list of variable value assignments that can be summoned in a program without actually defining the variables outside of the context of the operation using them. That's kind of neat. I'd have to try that out and see if it makes a program easier to write or understand. But I suspect that's just the tip of the iceberg (as is everything else in the Wolfram language). What do you say is the superpower in using associations?
|
|
Hey Carl! Indeed, you can think of associations as constituting some "local map" between keys and values (and indeed, that might be part of the reason why they can be "indexed" with single brackets like functions can, though this is just a wild guess). The primary value of associations in my view comes from the the organizational structure. For example, suppose I have a nested association:
scores=<|"Bob"-><|"Geography"->100,"Mathematics"->80,"Chemistry"->90|>,
"Alice"-><|"Geography"->90,"Mathematics"->100,"Chemistry"->85|>,
"Carol"-><|"Geography"->Missing["Absent"],"Mathematics"->100,"Chemistry"->95|>|>,
Now, without needing to remember which student or score is where, I can do something like:
scores["Bob"]
or:
scores["Bob","Chemistry"]
or:
scores[[All,"Mathematics"]]
This can be very useful for obvious reasons, especially as datasets get larger and more complicated. We'll discuss this more later in the course, but you may recall that pure functions work with numbered, unnamed slots:
#1+#2&[a,b]
returns:
a+b
But this isn't the only way they can work—they can work with slots named by keys as well:
#cat+#dog&[<|"cat"->1,"dog"->2|>]
will return 3 . This lets you write code that not only extracts the appropriate parts very easy, but performs various queries in a super readable and simple way. For example, the following code will select any students who have a chemistry score of 90 or higher:
Select[scores,#Chemistry≥90&]
Finally, from a technical perspective, it is faster to add or remove key-value pairs to an association than to add or remove elements with a list. This doesn't really crop up at the example scales we're talking about here, but can have an effect at larger sizes.
|
|
Hi arben,
Yes this is the tip of iceberg. I suggest you hash table as something to know. O(1) as a search algorithm. Hash tree and topology is a rich context to know
|
|
Hi everybody—I've added today's "filled-out" notebook to the materials folder. See you tomorrow!
|
|
The link in the email I received doesn't work. How do I navigate to the materials folder? I looked around and didn't see an obvious link.
|
|
Arben, how do I post without replying to someone else's post (like I am doing now)? I do have a question about Riffle[ ].
Riffle[{1,2,3}, {x, y}]
outputs {1,x,2,y,3}, understandably. But
Riffle[{x,y}, {1,2,3}]
outputs {x,1,y}. Why? I would have expected to get {x, 1, y, 2}. Thanks.
|
|
Daily recordings will be shared with the group each day, so you can catch up on any sessions you miss. Looking forward to it!
|
|
I can't make it at this time on MWF, but can on TTh.
|
|
Day 7: Found the notebook to download but not the "data" file. Where can I get this?
|
|
Almost missed this down at the bottom of the thread, but the amoeba folder should now have a data folder there!
|
|
Reply to this discussion
in reply to
|